comparison netio.c @ 1466:f787f60f8e45

bind to port as well with -b
author Matt Johnston <matt@ucc.asn.au>
date Fri, 26 Jan 2018 00:27:48 +0800
parents f7a53832501d
children 2d450c1056e3
comparison
equal deleted inserted replaced
1465:f7a53832501d 1466:f787f60f8e45
17 or NULL. */ 17 or NULL. */
18 18
19 int sock; 19 int sock;
20 20
21 char* errstring; 21 char* errstring;
22 struct addrinfo *bind_addrinfo; 22 char *bind_address, *bind_port;
23 }; 23 };
24 24
25 /* Deallocate a progress connection. Removes from the pending list if iter!=NULL. 25 /* Deallocate a progress connection. Removes from the pending list if iter!=NULL.
26 Does not close sockets */ 26 Does not close sockets */
27 static void remove_connect(struct dropbear_progress_connection *c, m_list_elem *iter) { 27 static void remove_connect(struct dropbear_progress_connection *c, m_list_elem *iter) {
29 freeaddrinfo(c->res); 29 freeaddrinfo(c->res);
30 } 30 }
31 m_free(c->remotehost); 31 m_free(c->remotehost);
32 m_free(c->remoteport); 32 m_free(c->remoteport);
33 m_free(c->errstring); 33 m_free(c->errstring);
34 if (c->bind_addrinfo) freeaddrinfo(c->bind_addrinfo); 34 m_free(c->bind_address);
35 m_free(c->bind_port);
35 m_free(c); 36 m_free(c);
36 37
37 if (iter) { 38 if (iter) {
38 list_remove(iter); 39 list_remove(iter);
39 } 40 }
51 c->cb_data = NULL; 52 c->cb_data = NULL;
52 } 53 }
53 54
54 static void connect_try_next(struct dropbear_progress_connection *c) { 55 static void connect_try_next(struct dropbear_progress_connection *c) {
55 struct addrinfo *r; 56 struct addrinfo *r;
57 int err;
56 int res = 0; 58 int res = 0;
57 int fastopen = 0; 59 int fastopen = 0;
58 #if DROPBEAR_CLIENT_TCP_FAST_OPEN 60 #if DROPBEAR_CLIENT_TCP_FAST_OPEN
59 struct msghdr message; 61 struct msghdr message;
60 #endif 62 #endif
66 c->sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol); 68 c->sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
67 if (c->sock < 0) { 69 if (c->sock < 0) {
68 continue; 70 continue;
69 } 71 }
70 72
71 if (c->bind_addrinfo) { 73 if (c->bind_address || c->bind_port) {
72 if (bind(c->sock, c->bind_addrinfo->ai_addr, c->bind_addrinfo->ai_addrlen) < 0) { 74 /* bind to a source port/address */
75 struct addrinfo hints;
76 struct addrinfo *bindaddr = NULL;
77 memset(&hints, 0, sizeof(hints));
78 hints.ai_socktype = SOCK_STREAM;
79 hints.ai_family = r->ai_family;
80 hints.ai_flags = AI_PASSIVE;
81
82 err = getaddrinfo(c->bind_address, c->bind_port, &hints, &bindaddr);
83 if (err) {
84 int len = 100 + strlen(gai_strerror(err));
85 m_free(c->errstring);
86 c->errstring = (char*)m_malloc(len);
87 snprintf(c->errstring, len, "Error resolving bind address '%s' (port %s). %s",
88 c->bind_address, c->bind_port, gai_strerror(err));
89 TRACE(("Error resolving bind: %s", gai_strerror(err)))
90 close(c->sock);
91 c->sock = -1;
92 continue;
93 }
94 res = bind(c->sock, bindaddr->ai_addr, bindaddr->ai_addrlen);
95 freeaddrinfo(bindaddr);
96 bindaddr = NULL;
97 if (res < 0) {
73 /* failure */ 98 /* failure */
99 int keep_errno = errno;
100 int len = 300;
74 m_free(c->errstring); 101 m_free(c->errstring);
75 c->errstring = m_strdup(strerror(errno)); 102 c->errstring = m_malloc(len);
103 snprintf(c->errstring, len, "Error binding local address '%s' (port %s). %s",
104 c->bind_address, c->bind_port, strerror(keep_errno));
76 close(c->sock); 105 close(c->sock);
77 c->sock = -1; 106 c->sock = -1;
78 continue; 107 continue;
79 } 108 }
80 } 109 }
141 } 170 }
142 } 171 }
143 172
144 /* Connect via TCP to a host. */ 173 /* Connect via TCP to a host. */
145 struct dropbear_progress_connection *connect_remote(const char* remotehost, const char* remoteport, 174 struct dropbear_progress_connection *connect_remote(const char* remotehost, const char* remoteport,
146 connect_callback cb, void* cb_data, char* bind_address) 175 connect_callback cb, void* cb_data,
176 const char* bind_address, const char* bind_port)
147 { 177 {
148 struct dropbear_progress_connection *c = NULL; 178 struct dropbear_progress_connection *c = NULL;
149 int err; 179 int err;
150 struct addrinfo hints; 180 struct addrinfo hints;
151 181
153 c->remotehost = m_strdup(remotehost); 183 c->remotehost = m_strdup(remotehost);
154 c->remoteport = m_strdup(remoteport); 184 c->remoteport = m_strdup(remoteport);
155 c->sock = -1; 185 c->sock = -1;
156 c->cb = cb; 186 c->cb = cb;
157 c->cb_data = cb_data; 187 c->cb_data = cb_data;
158 c->bind_addrinfo = NULL;
159 188
160 list_append(&ses.conn_pending, c); 189 list_append(&ses.conn_pending, c);
161 190
162 memset(&hints, 0, sizeof(hints)); 191 memset(&hints, 0, sizeof(hints));
163 hints.ai_socktype = SOCK_STREAM; 192 hints.ai_socktype = SOCK_STREAM;
173 TRACE(("Error resolving: %s", gai_strerror(err))) 202 TRACE(("Error resolving: %s", gai_strerror(err)))
174 } else { 203 } else {
175 c->res_iter = c->res; 204 c->res_iter = c->res;
176 } 205 }
177 206
178 if (NULL != bind_address) { 207 if (bind_address) {
179 memset(&hints, 0, sizeof(hints)); 208 c->bind_address = m_strdup(bind_address);
180 hints.ai_socktype = SOCK_STREAM; 209 }
181 hints.ai_family = AF_UNSPEC; 210 if (bind_port) {
182 err = getaddrinfo(bind_address, NULL, &hints, &c->bind_addrinfo); 211 c->bind_port = m_strdup(bind_port);
183 if (err) {
184 int len;
185 len = 100 + strlen(gai_strerror(err));
186 c->errstring = (char*)m_malloc(len);
187 snprintf(c->errstring, len, "Error resolving '%s'. %s",
188 bind_address, gai_strerror(err));
189 TRACE(("Error resolving: %s", gai_strerror(err)))
190 c->res_iter = NULL;
191 }
192 } 212 }
193 213
194 return c; 214 return c;
195 } 215 }
196 216