Changes in lib/proxy.c [dbca297:71abe93]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/proxy.c
rdbca297 r71abe93 51 51 #endif 52 52 53 static GHashTable *phb_hash = NULL;54 55 53 struct PHB { 56 54 b_event_handler func, proxy_func; … … 63 61 }; 64 62 65 typedef int (*proxy_connect_func)(const char *host, unsigned short port_, struct PHB *phb);66 67 63 static int proxy_connect_none(const char *host, unsigned short port_, struct PHB *phb); 68 64 69 static gboolean phb_free(struct PHB *phb, gboolean success) 70 { 71 g_hash_table_remove(phb_hash, &phb->fd); 72 73 if (!success) { 74 if (phb->fd > 0) { 75 closesocket(phb->fd); 76 } 77 if (phb->func) { 78 phb->func(phb->data, -1, B_EV_IO_READ); 79 } 80 } 81 if (phb->gai) { 82 freeaddrinfo(phb->gai); 83 } 65 static gboolean phb_close(struct PHB *phb) 66 { 67 close(phb->fd); 68 phb->func(phb->data, -1, B_EV_IO_READ); 84 69 g_free(phb->host); 85 70 g_free(phb); … … 104 89 dup2(new_fd, source); 105 90 closesocket(new_fd); 106 phb->fd = source;107 91 phb->inpa = b_input_add(source, B_EV_IO_WRITE, proxy_connected, phb); 108 92 return FALSE; … … 117 101 118 102 freeaddrinfo(phb->gai); 119 phb->gai = NULL;120 121 103 b_event_remove(phb->inpa); 122 104 phb->inpa = 0; 123 124 105 if (phb->proxy_func) { 125 106 phb->proxy_func(phb->proxy_data, source, B_EV_IO_READ); 126 107 } else { 127 108 phb->func(phb->data, source, B_EV_IO_READ); 128 phb_free(phb, TRUE);109 g_free(phb); 129 110 } 130 111 … … 190 171 191 172 if (fd < 0 && host) { 192 phb_free(phb, TRUE);173 g_free(phb); 193 174 } 194 175 … … 223 204 (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) { 224 205 phb->func(phb->data, source, B_EV_IO_READ); 225 return phb_free(phb, TRUE); 226 } 227 228 return phb_free(phb, FALSE); 206 g_free(phb->host); 207 g_free(phb); 208 return FALSE; 209 } 210 211 return phb_close(phb); 229 212 } 230 213 … … 241 224 len = sizeof(error); 242 225 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 243 return phb_ free(phb, FALSE);226 return phb_close(phb); 244 227 } 245 228 sock_make_blocking(source); … … 248 231 phb->host, phb->port); 249 232 if (send(source, cmd, strlen(cmd), 0) < 0) { 250 return phb_ free(phb, FALSE);233 return phb_close(phb); 251 234 } 252 235 … … 259 242 g_free(t2); 260 243 if (send(source, cmd, strlen(cmd), 0) < 0) { 261 return phb_ free(phb, FALSE);244 return phb_close(phb); 262 245 } 263 246 } … … 265 248 g_snprintf(cmd, sizeof(cmd), "\r\n"); 266 249 if (send(source, cmd, strlen(cmd), 0) < 0) { 267 return phb_ free(phb, FALSE);250 return phb_close(phb); 268 251 } 269 252 … … 296 279 if (read(source, packet, 9) >= 4 && packet[1] == 90) { 297 280 phb->func(phb->data, source, B_EV_IO_READ); 298 return phb_free(phb, TRUE); 299 } 300 301 return phb_free(phb, FALSE); 281 g_free(phb->host); 282 g_free(phb); 283 return FALSE; 284 } 285 286 return phb_close(phb); 302 287 } 303 288 … … 309 294 socklen_t len; 310 295 int error = ETIMEDOUT; 311 gboolean is_socks4a = (proxytype == PROXY_SOCKS4A);312 296 313 297 if (phb->inpa > 0) { … … 316 300 len = sizeof(error); 317 301 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 318 return phb_ free(phb, FALSE);302 return phb_close(phb); 319 303 } 320 304 sock_make_blocking(source); 321 305 322 if (!is_socks4a && !(hp = gethostbyname(phb->host))) { 323 return phb_free(phb, FALSE); 306 /* XXX does socks4 not support host name lookups by the proxy? */ 307 if (!(hp = gethostbyname(phb->host))) { 308 return phb_close(phb); 324 309 } 325 310 … … 328 313 packet[2] = phb->port >> 8; 329 314 packet[3] = phb->port & 0xff; 330 if (is_socks4a) { 331 packet[4] = 0; 332 packet[5] = 0; 333 packet[6] = 0; 334 packet[7] = 1; 335 } else { 336 packet[4] = (unsigned char) (hp->h_addr_list[0])[0]; 337 packet[5] = (unsigned char) (hp->h_addr_list[0])[1]; 338 packet[6] = (unsigned char) (hp->h_addr_list[0])[2]; 339 packet[7] = (unsigned char) (hp->h_addr_list[0])[3]; 340 } 315 packet[4] = (unsigned char) (hp->h_addr_list[0])[0]; 316 packet[5] = (unsigned char) (hp->h_addr_list[0])[1]; 317 packet[6] = (unsigned char) (hp->h_addr_list[0])[2]; 318 packet[7] = (unsigned char) (hp->h_addr_list[0])[3]; 341 319 packet[8] = 0; 342 320 if (write(source, packet, 9) != 9) { 343 return phb_free(phb, FALSE); 344 } 345 346 if (is_socks4a) { 347 size_t host_len = strlen(phb->host) + 1; /* include the \0 */ 348 349 if (write(source, phb->host, host_len) != host_len) { 350 return phb_free(phb, FALSE); 351 } 321 return phb_close(phb); 352 322 } 353 323 … … 378 348 379 349 if (read(source, buf, 10) < 10) { 380 return phb_ free(phb, FALSE);350 return phb_close(phb); 381 351 } 382 352 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { 383 return phb_ free(phb, FALSE);353 return phb_close(phb); 384 354 } 385 355 386 356 phb->func(phb->data, source, B_EV_IO_READ); 387 return phb_free(phb, TRUE); 357 g_free(phb->host); 358 g_free(phb); 359 360 return FALSE; 388 361 } 389 362 … … 404 377 405 378 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { 406 phb_ free(phb, FALSE);379 phb_close(phb); 407 380 return; 408 381 } … … 419 392 420 393 if (read(source, buf, 2) < 2) { 421 return phb_ free(phb, FALSE);394 return phb_close(phb); 422 395 } 423 396 424 397 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { 425 return phb_ free(phb, FALSE);398 return phb_close(phb); 426 399 } 427 400 … … 439 412 440 413 if (read(source, buf, 2) < 2) { 441 return phb_ free(phb, FALSE);414 return phb_close(phb); 442 415 } 443 416 444 417 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { 445 return phb_ free(phb, FALSE);418 return phb_close(phb); 446 419 } 447 420 … … 454 427 memcpy(buf + 2 + i + 1, proxypass, j); 455 428 if (write(source, buf, 3 + i + j) < 3 + i + j) { 456 return phb_ free(phb, FALSE);429 return phb_close(phb); 457 430 } 458 431 … … 478 451 len = sizeof(error); 479 452 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 480 return phb_ free(phb, FALSE);453 return phb_close(phb); 481 454 } 482 455 sock_make_blocking(source); … … 496 469 497 470 if (write(source, buf, i) < i) { 498 return phb_ free(phb, FALSE);471 return phb_close(phb); 499 472 } 500 473 … … 514 487 } 515 488 516 static const proxy_connect_func proxy_connect_funcs_array[] = {517 proxy_connect_none, /* PROXY_NONE */518 proxy_connect_http, /* PROXY_HTTP */519 proxy_connect_socks4, /* PROXY_SOCKS4 */520 proxy_connect_socks5, /* PROXY_SOCKS5 */521 proxy_connect_socks4, /* PROXY_SOCKS4A */522 };523 489 524 490 /* Export functions */ … … 527 493 { 528 494 struct PHB *phb; 529 proxy_connect_func fun;530 int fd;531 532 if (!phb_hash) {533 phb_hash = g_hash_table_new(g_int_hash, g_int_equal);534 }535 495 536 496 if (!host || port <= 0 || !func || strlen(host) > 128) { … … 542 502 phb->data = data; 543 503 544 if (proxyhost[0] && proxyport > 0 && proxytype >= 0 && proxytype < G_N_ELEMENTS(proxy_connect_funcs_array)) { 545 fun = proxy_connect_funcs_array[proxytype]; 546 } else { 547 fun = proxy_connect_none; 548 } 549 550 fd = fun(host, port, phb); 551 552 if (fd != -1) { 553 g_hash_table_insert(phb_hash, &phb->fd, phb); 554 } 555 556 return fd; 557 } 558 559 void proxy_disconnect(int fd) 560 { 561 struct PHB *phb = g_hash_table_lookup(phb_hash, &fd); 562 563 if (!phb) { 564 /* not in the early part of the connection - just close the fd */ 565 closesocket(fd); 566 return; 567 } 568 569 if (phb->inpa) { 570 b_event_remove(phb->inpa); 571 phb->inpa = 0; 572 } 573 574 /* avoid calling the callback, which might result in double-free */ 575 phb->func = NULL; 576 577 /* close and free */ 578 phb_free(phb, FALSE); 579 } 504 if (proxytype == PROXY_NONE || !proxyhost[0] || proxyport <= 0) { 505 return proxy_connect_none(host, port, phb); 506 } else if (proxytype == PROXY_HTTP) { 507 return proxy_connect_http(host, port, phb); 508 } else if (proxytype == PROXY_SOCKS4) { 509 return proxy_connect_socks4(host, port, phb); 510 } else if (proxytype == PROXY_SOCKS5) { 511 return proxy_connect_socks5(host, port, phb); 512 } 513 514 g_free(phb); 515 return -1; 516 }
Note: See TracChangeset
for help on using the changeset viewer.