masqmail

view src/connect.c @ 378:5781ba87df95

Removed ident. This had been discussed on the mailing list in Oct 2011. Ident is hardly useful in typical setups for masqmail. Probably Oliver had used it in his setup; that would make sense. Now, I know of nobody who needs it.
author markus schnalke <meillo@marmaro.de>
date Sat, 14 Jan 2012 21:36:58 +0100
parents b27f66555ba8
children 6500db550a03
line source
1 /*
2 ** MasqMail
3 ** Copyright (C) 1999 Oliver Kurth
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 #include "masqmail.h"
21 static GList*
22 resolve_ip(GList *list, gchar *ip)
23 {
24 struct in_addr ia;
25 if (inet_aton(ip, &ia)) {
26 mxip_addr mxip;
28 mxip.name = g_strdup(ip);
29 mxip.pref = 0;
30 mxip.ip = (guint32) * (guint32 *) (&ia);
31 list = g_list_append(list, g_memdup(&mxip, sizeof(mxip)));
32 }
33 /* logwrite(LOG_ALERT, "invalid address '%s': inet_aton() failed\n", ip); */
34 return NULL;
35 }
37 mxip_addr*
38 connect_hostlist(int *psockfd, gchar *host, guint port, GList *addr_list)
39 {
40 GList *addr_node;
41 struct sockaddr_in saddr;
43 DEBUG(5) debugf("connect_hostlist entered\n");
45 for (addr_node = g_list_first(addr_list); addr_node; addr_node = g_list_next(addr_node)) {
46 mxip_addr *addr = (mxip_addr *) (addr_node->data);
48 *psockfd = socket(PF_INET, SOCK_STREAM, 0);
50 memset(&saddr, 0, sizeof(saddr));
52 saddr.sin_family = AF_INET;
53 saddr.sin_port = htons(port);
55 /* clumsy, but makes compiler happy: */
56 saddr.sin_addr = *(struct in_addr *) (&(addr->ip));
57 DEBUG(5) debugf(" trying ip %s port %d\n", inet_ntoa(saddr.sin_addr), port);
58 if (connect(*psockfd, (struct sockaddr *) (&saddr), sizeof(saddr)) == 0) {
59 DEBUG(5) debugf(" connected to %s\n", inet_ntoa(saddr.sin_addr));
60 return addr;
61 } else {
62 int saved_errno = errno;
64 close(*psockfd);
66 logwrite(LOG_WARNING, "connection to %s failed: %s\n", inet_ntoa(saddr.sin_addr), strerror(errno));
68 errno = saved_errno;
70 if ((saved_errno != ECONNREFUSED)
71 && (saved_errno != ETIMEDOUT)
72 && (saved_errno != ENETUNREACH)
73 && (saved_errno != EHOSTUNREACH))
74 return NULL;
75 }
76 }
77 return NULL;
78 }
80 /*
81 ** Given a list of resolver functions, this function
82 ** resolve the host and tries to connect to the addresses
83 ** returned. If a connection attemp is timed out or refused,
84 ** the next address is tried.
85 **
86 ** TODO: the resolver functions might return duplicate addresses,
87 ** if attempt failed for one it should not be tried again.
88 */
89 mxip_addr*
90 connect_resolvelist(int *psockfd, gchar *host, guint port, GList *res_func_list)
91 {
92 GList *res_node;
93 GList *addr_list;
95 DEBUG(5) debugf("connect_resolvelist entered\n");
97 h_errno = 0;
99 if (isdigit(host[0])) {
100 mxip_addr *addr;
102 addr_list = resolve_ip(NULL, host);
103 if (addr_list) {
104 addr = connect_hostlist(psockfd, host, port, addr_list);
105 g_list_free(addr_list);
106 return addr;
107 }
108 /*
109 ** previous versions complained, until someone tried
110 ** to use a hostname out there that begins with a
111 ** digit. eg. '3dwars.de'.
112 */
113 }
115 if (res_func_list == NULL) {
116 logwrite(LOG_ALERT, "res_funcs == NULL !!!\n");
117 exit(1);
118 }
120 foreach(res_func_list, res_node) {
121 resolve_func res_func;
122 DEBUG(6) debugf(" foreach() body\n");
123 res_func = (resolve_func) (res_node->data);
125 if (res_func == NULL) {
126 logwrite(LOG_ALERT, "res_func == NULL !!!\n");
127 exit(1);
128 }
130 errno = 0;
131 if ((addr_list = res_func(NULL, host))) {
133 mxip_addr *addr;
134 if ((addr = connect_hostlist(psockfd, host, port, addr_list)))
135 return addr;
137 DEBUG(5) {
138 debugf("connect_hostlist failed: %s\n", strerror(errno));
139 }
141 g_list_free(addr_list);
142 } else if (!g_list_next(res_node)) {
143 logwrite(LOG_ALERT, "could not resolve %s: %s\n", host, hstrerror(h_errno));
144 }
145 }
146 return NULL;
148 }