comparison src/connect.c @ 401:885e3d886199

Various minor refactoring.
author markus schnalke <meillo@marmaro.de>
date Tue, 21 Feb 2012 16:11:00 +0100
parents 6500db550a03
children
comparison
equal deleted inserted replaced
400:6500db550a03 401:885e3d886199
37 mxip_addr* 37 mxip_addr*
38 connect_hostlist(int *psockfd, gchar *host, guint port, GList *addr_list) 38 connect_hostlist(int *psockfd, gchar *host, guint port, GList *addr_list)
39 { 39 {
40 GList *addr_node; 40 GList *addr_node;
41 struct sockaddr_in saddr; 41 struct sockaddr_in saddr;
42 int saved_errno;
42 43
43 DEBUG(5) debugf("connect_hostlist entered\n"); 44 DEBUG(5) debugf("connect_hostlist entered\n");
44 45
45 for (addr_node = g_list_first(addr_list); addr_node; addr_node = g_list_next(addr_node)) { 46 for (addr_node = g_list_first(addr_list); addr_node;
47 addr_node = g_list_next(addr_node)) {
46 mxip_addr *addr = (mxip_addr *) (addr_node->data); 48 mxip_addr *addr = (mxip_addr *) (addr_node->data);
47
48 *psockfd = socket(PF_INET, SOCK_STREAM, 0); 49 *psockfd = socket(PF_INET, SOCK_STREAM, 0);
49 50
50 memset(&saddr, 0, sizeof(saddr)); 51 memset(&saddr, 0, sizeof(saddr));
51
52 saddr.sin_family = AF_INET; 52 saddr.sin_family = AF_INET;
53 saddr.sin_port = htons(port); 53 saddr.sin_port = htons(port);
54
55 /* clumsy, but makes compiler happy: */ 54 /* clumsy, but makes compiler happy: */
56 saddr.sin_addr = *(struct in_addr *) (&(addr->ip)); 55 saddr.sin_addr = *(struct in_addr *) (&(addr->ip));
57 DEBUG(5) debugf(" trying ip %s port %d\n", inet_ntoa(saddr.sin_addr), port); 56
58 if (connect(*psockfd, (struct sockaddr *) (&saddr), sizeof(saddr)) == 0) { 57 DEBUG(5) debugf(" trying ip %s port %d\n",
59 DEBUG(5) debugf(" connected to %s\n", inet_ntoa(saddr.sin_addr)); 58 inet_ntoa(saddr.sin_addr), port);
59
60 if (connect(*psockfd, (struct sockaddr *) &saddr,
61 sizeof(saddr))==0) {
62 DEBUG(5) debugf(" connected to %s\n",
63 inet_ntoa(saddr.sin_addr));
60 return addr; 64 return addr;
61 } else { 65 }
62 int saved_errno = errno;
63 66
64 close(*psockfd); 67 saved_errno = errno;
68 close(*psockfd);
69 logwrite(LOG_WARNING, "connection to %s failed: %s\n",
70 inet_ntoa(saddr.sin_addr), strerror(errno));
71 errno = saved_errno;
65 72
66 logwrite(LOG_WARNING, "connection to %s failed: %s\n", inet_ntoa(saddr.sin_addr), strerror(errno)); 73 if ((saved_errno != ECONNREFUSED) &&
67 74 (saved_errno != ETIMEDOUT) &&
68 errno = saved_errno; 75 (saved_errno != ENETUNREACH) &&
69 76 (saved_errno != EHOSTUNREACH)) {
70 if ((saved_errno != ECONNREFUSED) 77 return NULL;
71 && (saved_errno != ETIMEDOUT)
72 && (saved_errno != ENETUNREACH)
73 && (saved_errno != EHOSTUNREACH))
74 return NULL;
75 } 78 }
76 } 79 }
77 return NULL; 80 return NULL;
78 } 81 }
79 82
85 ** 88 **
86 ** TODO: the resolver functions might return duplicate addresses, 89 ** TODO: the resolver functions might return duplicate addresses,
87 ** if attempt failed for one it should not be tried again. 90 ** if attempt failed for one it should not be tried again.
88 */ 91 */
89 mxip_addr* 92 mxip_addr*
90 connect_resolvelist(int *psockfd, gchar *host, guint port, GList *res_func_list) 93 connect_resolvelist(int *psockfd, gchar *host, guint port,
94 GList *res_func_list)
91 { 95 {
92 GList *res_node; 96 GList *res_node;
93 GList *addr_list; 97 GList *addr_list;
94 98
95 DEBUG(5) debugf("connect_resolvelist entered\n"); 99 DEBUG(5) debugf("connect_resolvelist entered\n");
96 100
97 h_errno = 0; 101 h_errno = 0;
98
99 if (isdigit(*host)) { 102 if (isdigit(*host)) {
100 mxip_addr *addr; 103 mxip_addr *addr;
101 104
102 if ((addr_list = resolve_ip(host))) { 105 if ((addr_list = resolve_ip(host))) {
103 addr = connect_hostlist(psockfd, host, port, addr_list); 106 addr = connect_hostlist(psockfd, host, port,
107 addr_list);
104 g_list_free(addr_list); 108 g_list_free(addr_list);
105 return addr; 109 return addr;
106 } 110 }
107 /* 111 /*
108 ** Probably a hostname that begins with a digit. 112 ** Probably a hostname that begins with a digit.
109 ** E.g. '3dwars.de'. Thus fall ... 113 ** E.g. '3dwars.de'. Thus fall ...
110 */ 114 */
111 } 115 }
112 116
113 if (res_func_list == NULL) { 117 if (!res_func_list) {
114 logwrite(LOG_ALERT, "res_funcs == NULL !!!\n"); 118 logwrite(LOG_ALERT, "res_funcs not set!\n");
115 exit(1); 119 exit(1);
116 } 120 }
117 121
118 foreach(res_func_list, res_node) { 122 foreach(res_func_list, res_node) {
119 resolve_func res_func; 123 resolve_func res_func;
120 DEBUG(6) debugf(" foreach() body\n"); 124 DEBUG(6) debugf(" foreach() body\n");
121 res_func = (resolve_func) (res_node->data);
122 125
123 if (res_func == NULL) { 126 res_func = (resolve_func) res_node->data;
124 logwrite(LOG_ALERT, "res_func == NULL !!!\n"); 127 if (!res_func) {
128 logwrite(LOG_ALERT, "Empty res_func!\n");
125 exit(1); 129 exit(1);
126 } 130 }
127 131
128 errno = 0; 132 errno = 0;
129 if ((addr_list = res_func(NULL, host))) { 133 if ((addr_list = res_func(NULL, host))) {
130 134
131 mxip_addr *addr; 135 mxip_addr *addr;
132 if ((addr = connect_hostlist(psockfd, host, port, addr_list))) 136 if ((addr = connect_hostlist(psockfd, host, port,
137 addr_list))) {
133 return addr; 138 return addr;
134
135 DEBUG(5) {
136 debugf("connect_hostlist failed: %s\n", strerror(errno));
137 } 139 }
138 140 DEBUG(5) debugf("connect_hostlist failed: %s\n",
141 strerror(errno));
139 g_list_free(addr_list); 142 g_list_free(addr_list);
140 } else if (!g_list_next(res_node)) { 143 } else if (!g_list_next(res_node)) {
141 logwrite(LOG_ALERT, "could not resolve %s: %s\n", host, hstrerror(h_errno)); 144 logwrite(LOG_ALERT, "could not resolve %s: %s\n",
145 host, hstrerror(h_errno));
142 } 146 }
143 } 147 }
144 return NULL; 148 return NULL;
145 149
146 } 150 }