comparison src/connect.c @ 10:26e34ae9a3e3

changed indention and line wrapping to a more consistent style
author meillo@marmaro.de
date Mon, 27 Oct 2008 16:23:10 +0100
parents 08114f7dcc23
children a80ebfa16cd5
comparison
equal deleted inserted replaced
9:31cc8a89cb74 10:26e34ae9a3e3
15 along with this program; if not, write to the Free Software 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18 #include "masqmail.h" 18 #include "masqmail.h"
19 19
20 static 20 static GList*
21 GList *resolve_ip(GList *list, gchar *ip) 21 resolve_ip(GList * list, gchar * ip)
22 { 22 {
23 struct in_addr ia; 23 struct in_addr ia;
24 if(inet_aton(ip, &ia)){ 24 if (inet_aton(ip, &ia)) {
25 mxip_addr mxip; 25 mxip_addr mxip;
26 26
27 mxip.name = g_strdup(ip); 27 mxip.name = g_strdup(ip);
28 mxip.pref = 0; 28 mxip.pref = 0;
29 mxip.ip = (guint32) *(guint32 *)(&ia); 29 mxip.ip = (guint32) * (guint32 *) (&ia);
30 list = g_list_append(list, g_memdup(&mxip, sizeof(mxip))); 30 list = g_list_append(list, g_memdup(&mxip, sizeof(mxip)));
31 } 31 }
32 /* logwrite(LOG_ALERT, "invalid address '%s': inet_aton() failed\n", ip);*/ 32 /* logwrite(LOG_ALERT, "invalid address '%s': inet_aton() failed\n", ip); */
33 return NULL; 33 return NULL;
34 } 34 }
35 35
36 mxip_addr *connect_hostlist(int *psockfd, gchar *host, guint port, 36 mxip_addr*
37 GList *addr_list) 37 connect_hostlist(int *psockfd, gchar * host, guint port, GList * addr_list)
38 { 38 {
39 GList *addr_node; 39 GList *addr_node;
40 struct sockaddr_in saddr; 40 struct sockaddr_in saddr;
41 41
42 DEBUG(5) debugf("connect_hostlist entered\n"); 42 DEBUG(5) debugf("connect_hostlist entered\n");
43 43
44 for(addr_node = g_list_first(addr_list); 44 for (addr_node = g_list_first(addr_list); addr_node; addr_node = g_list_next(addr_node)) {
45 addr_node; 45 mxip_addr *addr = (mxip_addr *) (addr_node->data);
46 addr_node = g_list_next(addr_node)){
47 mxip_addr *addr = (mxip_addr *)(addr_node->data);
48 46
49 *psockfd = socket(PF_INET, SOCK_STREAM, 0); 47 *psockfd = socket(PF_INET, SOCK_STREAM, 0);
50 48
51 memset(&saddr, 0, sizeof(saddr)); 49 memset(&saddr, 0, sizeof(saddr));
52 50
53 saddr.sin_family = AF_INET; 51 saddr.sin_family = AF_INET;
54 saddr.sin_port = htons(port); 52 saddr.sin_port = htons(port);
55 53
56 /* clumsy, but makes compiler happy: */ 54 /* clumsy, but makes compiler happy: */
57 saddr.sin_addr = *(struct in_addr*)(&(addr->ip)); 55 saddr.sin_addr = *(struct in_addr *) (&(addr->ip));
58 DEBUG(5) debugf("trying ip %s port %d\n", inet_ntoa(saddr.sin_addr), port); 56 DEBUG(5) debugf("trying ip %s port %d\n", inet_ntoa(saddr.sin_addr), port);
59 if(connect(*psockfd, (struct sockaddr *)(&saddr), sizeof(saddr)) == 0){ 57 if (connect(*psockfd, (struct sockaddr *) (&saddr), sizeof(saddr)) == 0) {
60 DEBUG(5) debugf("connected to %s\n", inet_ntoa(saddr.sin_addr)); 58 DEBUG(5) debugf("connected to %s\n", inet_ntoa(saddr.sin_addr));
61 return addr; 59 return addr;
62 }else{ 60 } else {
63 int saved_errno = errno; 61 int saved_errno = errno;
64 62
65 close(*psockfd); 63 close(*psockfd);
66 64
67 logwrite(LOG_WARNING, "connection to %s failed: %s\n", 65 logwrite(LOG_WARNING, "connection to %s failed: %s\n", inet_ntoa(saddr.sin_addr), strerror(errno));
68 inet_ntoa(saddr.sin_addr), strerror(errno));
69 66
70 errno = saved_errno; 67 errno = saved_errno;
71 68
72 if((saved_errno != ECONNREFUSED) && 69 if ((saved_errno != ECONNREFUSED)
73 (saved_errno != ETIMEDOUT) && 70 && (saved_errno != ETIMEDOUT)
74 (saved_errno != ENETUNREACH) && 71 && (saved_errno != ENETUNREACH)
75 (saved_errno != EHOSTUNREACH)) 72 && (saved_errno != EHOSTUNREACH))
76 73 return NULL;
74 }
75 }
77 return NULL; 76 return NULL;
78 }
79 }
80 return NULL;
81 } 77 }
82 78
83 /* Given a list of resolver functions, this function 79 /* Given a list of resolver functions, this function
84 resolve the host and tries to connect to the addresses 80 resolve the host and tries to connect to the addresses
85 returned. If a connection attemp is timed out or refused, 81 returned. If a connection attemp is timed out or refused,
87 83
88 TODO: the resolver functions might return duplicate addresses, 84 TODO: the resolver functions might return duplicate addresses,
89 if attempt failed for one it should not be tried again. 85 if attempt failed for one it should not be tried again.
90 */ 86 */
91 87
92 mxip_addr *connect_resolvelist(int *psockfd, gchar *host, guint port, 88 mxip_addr*
93 GList *res_func_list) 89 connect_resolvelist(int *psockfd, gchar * host, guint port, GList * res_func_list)
94 { 90 {
95 GList *res_node; 91 GList *res_node;
96 GList *addr_list; 92 GList *addr_list;
97 93
98 DEBUG(5) debugf("connect_resolvelist entered\n"); 94 DEBUG(5) debugf("connect_resolvelist entered\n");
99 95
100 h_errno = 0; 96 h_errno = 0;
101 97
102 if(isdigit(host[0])){ 98 if (isdigit(host[0])) {
103 mxip_addr *addr; 99 mxip_addr *addr;
104
105 addr_list = resolve_ip(NULL, host);
106 if(addr_list){
107 addr = connect_hostlist(psockfd, host, port, addr_list);
108 g_list_free(addr_list);
109 return addr;
110 }
111 /* previous versions complained, until someone tried to use a hostname
112 out there that begins with a digit. eg. '3dwars.de'. */
113 }
114 100
115 if(res_func_list == NULL){ 101 addr_list = resolve_ip(NULL, host);
116 logwrite(LOG_ALERT, "res_funcs == NULL !!!\n"); 102 if (addr_list) {
117 exit(EXIT_FAILURE); 103 addr = connect_hostlist(psockfd, host, port, addr_list);
118 } 104 g_list_free(addr_list);
105 return addr;
106 }
107 /* previous versions complained, until someone tried to use a hostname
108 out there that begins with a digit. eg. '3dwars.de'. */
109 }
119 110
120 foreach(res_func_list, res_node){ 111 if (res_func_list == NULL) {
121 resolve_func res_func; 112 logwrite(LOG_ALERT, "res_funcs == NULL !!!\n");
122 DEBUG(6) debugf("connect_resolvelist 1a\n"); 113 exit(EXIT_FAILURE);
123 res_func = (resolve_func)(res_node->data); 114 }
124
125 if(res_func == NULL){
126 logwrite(LOG_ALERT, "res_func == NULL !!!\n");
127 exit(EXIT_FAILURE);
128 }
129
130 errno = 0;
131 if((addr_list = res_func(NULL, host))){
132
133 mxip_addr *addr;
134 if((addr = connect_hostlist(psockfd, host, port, addr_list)))
135 return addr;
136 115
137 DEBUG(5){ 116 foreach(res_func_list, res_node) {
138 debugf("connect_hostlist failed: %s\n", strerror(errno)); 117 resolve_func res_func;
139 } 118 DEBUG(6) debugf("connect_resolvelist 1a\n");
140 119 res_func = (resolve_func) (res_node->data);
141 g_list_free(addr_list); 120
142 }else{ 121 if (res_func == NULL) {
143 if(!g_list_next(res_node)){ 122 logwrite(LOG_ALERT, "res_func == NULL !!!\n");
144 logwrite(LOG_ALERT, "could not resolve %s: %s\n", host, hstrerror(h_errno)); 123 exit(EXIT_FAILURE);
145 } 124 }
146 } 125
147 } 126 errno = 0;
148 return NULL; 127 if ((addr_list = res_func(NULL, host))) {
128
129 mxip_addr *addr;
130 if ((addr = connect_hostlist(psockfd, host, port, addr_list)))
131 return addr;
132
133 DEBUG(5) {
134 debugf("connect_hostlist failed: %s\n", strerror(errno));
135 }
136
137 g_list_free(addr_list);
138 } else {
139 if (!g_list_next(res_node)) {
140 logwrite(LOG_ALERT, "could not resolve %s: %s\n", host, hstrerror(h_errno));
141 }
142 }
143 }
144 return NULL;
149 145
150 } 146 }
151