Mercurial > hg > nnchat
comparison libnnchat.c @ 359:8f3c102db611
Fix SOCKS handling.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 23 Jun 2011 10:11:45 +0300 |
parents | ba2aa110755b |
children | b465a17ffa47 |
comparison
equal
deleted
inserted
replaced
358:98a3c525266b | 359:8f3c102db611 |
---|---|
185 FD_SET(conn->socket, &(conn->sockfds)); | 185 FD_SET(conn->socket, &(conn->sockfds)); |
186 | 186 |
187 /* Proxy-specific setup */ | 187 /* Proxy-specific setup */ |
188 if (conn->proxy.type == NN_PROXY_SOCKS4 || conn->proxy.type == NN_PROXY_SOCKS4A) { | 188 if (conn->proxy.type == NN_PROXY_SOCKS4 || conn->proxy.type == NN_PROXY_SOCKS4A) { |
189 struct nn_socks_t *socksh; | 189 struct nn_socks_t *socksh; |
190 size_t bufsiz = sizeof(struct nn_socks_t) + strlen(userid) + 1 + strlen(conn->host) + 1; | 190 size_t bufsiz = sizeof(struct nn_socks_t) + strlen(userid) + 1; |
191 char *ptr, *buf; | 191 char *ptr, *buf; |
192 int tries, status = -1; | 192 int tries, status = -1; |
193 | |
194 if (conn->proxy.type == NN_PROXY_SOCKS4A) | |
195 bufsiz += strlen(conn->host) + 1; | |
193 | 196 |
194 ptr = buf = th_malloc(bufsiz); | 197 ptr = buf = th_malloc(bufsiz); |
195 if (buf == NULL) { | 198 if (buf == NULL) { |
196 conn->err = -1; | 199 conn->err = -1; |
197 nn_conn_err(conn, "Could not allocate memory for SOCKS negotiation buffer, %d bytes.\n", bufsiz); | 200 nn_conn_err(conn, "Could not allocate memory for SOCKS negotiation buffer, %d bytes.\n", bufsiz); |
209 else | 212 else |
210 socksh->addr = conn->addr.s_addr; | 213 socksh->addr = conn->addr.s_addr; |
211 ptr += sizeof(struct nn_socks_t); | 214 ptr += sizeof(struct nn_socks_t); |
212 | 215 |
213 strcpy(ptr, userid); | 216 strcpy(ptr, userid); |
214 ptr += strlen(userid) + 1; | 217 |
215 | 218 if (conn->proxy.type == NN_PROXY_SOCKS4A) { |
216 strcpy(ptr, conn->host); | 219 ptr += strlen(userid) + 1; |
220 strcpy(ptr, conn->host); | |
221 } | |
217 | 222 |
218 /* Send request */ | 223 /* Send request */ |
219 if (!nn_conn_send_buf(conn, buf, bufsiz)) { | 224 if (!nn_conn_send_buf(conn, buf, bufsiz)) { |
220 th_free(buf); | 225 th_free(buf); |
221 nn_conn_err(conn, "Error sending SOCKS proxy request.\n"); | 226 nn_conn_err(conn, "Error sending SOCKS proxy request.\n"); |
222 goto error; | 227 goto error; |
223 } | 228 } |
224 th_free(buf); | 229 th_free(buf); |
225 | 230 |
226 /* Wait for SOCKS server to reply */ | 231 /* Wait for SOCKS server to reply */ |
227 for (tries = 0; tries < 20; tries++) { | 232 for (status = tries = 1; tries <= 20 && status > 0; tries++) { |
228 usleep(500); | 233 usleep(500); |
229 status = nn_conn_pull(conn); | 234 status = nn_conn_pull(conn); |
230 if (status <= 0) break; | |
231 } | 235 } |
232 | 236 |
233 /* Check results */ | 237 /* Check results */ |
234 if (status == 0) { | 238 if (status == 0) { |
235 struct nn_socks_res_t *res = (struct nn_socks_res_t *) &(conn->buf); | 239 struct nn_socks_res_t *res = (struct nn_socks_res_t *) &(conn->buf); |
249 goto error; | 253 goto error; |
250 } | 254 } |
251 nn_conn_msg(conn, "SOCKS connection established!\n"); | 255 nn_conn_msg(conn, "SOCKS connection established!\n"); |
252 } | 256 } |
253 else if (status < 0) { | 257 else if (status < 0) { |
254 nn_conn_err(conn, "Proxy negotiation failed with network error: %d\n", status); | 258 nn_conn_err(conn, "Proxy negotiation failed at try %d with network error: %d\n", tries, status); |
255 goto error; | 259 goto error; |
256 } | 260 } |
257 else { | 261 else { |
258 nn_conn_err(conn, "Proxy negotiation timed out.\n"); | 262 nn_conn_err(conn, "Proxy negotiation timed out.\n"); |
259 goto error; | 263 goto error; |
318 int result; | 322 int result; |
319 struct timeval socktv; | 323 struct timeval socktv; |
320 fd_set tmpfds; | 324 fd_set tmpfds; |
321 | 325 |
322 if (conn == NULL) | 326 if (conn == NULL) |
323 return -1; | 327 return -10; |
324 | 328 |
325 conn->ptr = conn->buf; | 329 conn->ptr = conn->buf; |
326 | 330 |
327 /* Check for incoming data */ | 331 /* Check for incoming data */ |
328 socktv.tv_sec = 0; | 332 socktv.tv_sec = 0; |
336 socket, conn->err, nn_get_socket_errstr(conn->err)); | 340 socket, conn->err, nn_get_socket_errstr(conn->err)); |
337 return -1; | 341 return -1; |
338 } | 342 } |
339 } else | 343 } else |
340 if (FD_ISSET(conn->socket, &tmpfds)) { | 344 if (FD_ISSET(conn->socket, &tmpfds)) { |
341 conn->got = recv(conn->socket, conn->ptr, NN_CONNBUF_SIZE, 0); | 345 conn->got = recv(conn->socket, conn->buf, NN_CONNBUF_SIZE, 0); |
342 if (conn->got < 0) { | 346 if (conn->got < 0) { |
343 conn->err = nn_get_socket_errno(); | 347 conn->err = nn_get_socket_errno(); |
344 nn_conn_err(conn, "Error in recv: %d, %s\n", conn->err, nn_get_socket_errstr(conn->err)); | 348 nn_conn_err(conn, "Error in recv: %d, %s\n", conn->err, nn_get_socket_errstr(conn->err)); |
345 return -2; | 349 return -2; |
346 } else if (conn->got == 0) { | 350 } else if (conn->got == 0) { |