Mercurial > masqmail
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 |