src/protocols/oscar/conn.c

changeset 3630
caa952062dc2
parent 3023
e6901b85c423
child 3694
49a336931cc6
equal deleted inserted replaced
3629:d166c9f8c50f 3630:caa952062dc2
12 12
13 #ifndef _WIN32 13 #ifndef _WIN32
14 #include <netdb.h> 14 #include <netdb.h>
15 #include <sys/socket.h> 15 #include <sys/socket.h>
16 #include <netinet/in.h> 16 #include <netinet/in.h>
17 #else
18 #include <winsock.h>
17 #endif 19 #endif
18 20
19 /* 21 /*
20 * In OSCAR, every connection has a set of SNAC groups associated 22 * In OSCAR, every connection has a set of SNAC groups associated
21 * with it. These are the groups that you can send over this connection 23 * with it. These are the groups that you can send over this connection
315 */ 317 */
316 faim_export void aim_conn_close(aim_conn_t *deadconn) 318 faim_export void aim_conn_close(aim_conn_t *deadconn)
317 { 319 {
318 320
319 if (deadconn->fd >= 3) 321 if (deadconn->fd >= 3)
322 #ifndef _WIN32
320 close(deadconn->fd); 323 close(deadconn->fd);
324 #else
325 closesocket(deadconn->fd);
326 #endif
321 deadconn->fd = -1; 327 deadconn->fd = -1;
322 if (deadconn->handlerlist) 328 if (deadconn->handlerlist)
323 aim_clearhandlers(deadconn); 329 aim_clearhandlers(deadconn);
324 if (deadconn->type == AIM_CONN_TYPE_RENDEZVOUS) 330 if (deadconn->type == AIM_CONN_TYPE_RENDEZVOUS)
325 aim_conn_close_rend((aim_session_t *)deadconn->sessv, deadconn); 331 aim_conn_close_rend((aim_session_t *)deadconn->sessv, deadconn);
427 sa.sin_family = hp->h_addrtype; 433 sa.sin_family = hp->h_addrtype;
428 434
429 fd = socket(hp->h_addrtype, SOCK_STREAM, 0); 435 fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
430 if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { 436 if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
431 faimdprintf(sess, 0, "proxyconnect: unable to connect to proxy\n"); 437 faimdprintf(sess, 0, "proxyconnect: unable to connect to proxy\n");
438 #ifndef _WIN32
432 close(fd); 439 close(fd);
440 #else
441 closesocket(fd);
442 #endif
433 return -1; 443 return -1;
434 } 444 }
435 445
436 i = 0; 446 i = 0;
437 buf[0] = 0x05; /* SOCKS version 5 */ 447 buf[0] = 0x05; /* SOCKS version 5 */
443 } else { 453 } else {
444 buf[1] = 0x01; 454 buf[1] = 0x01;
445 buf[2] = 0x00; 455 buf[2] = 0x00;
446 i = 3; 456 i = 3;
447 } 457 }
448 458 #ifndef _WIN32
449 if (write(fd, buf, i) < i) { 459 if (write(fd, buf, i) < i) {
460 #else
461 if (send(fd, buf, i, 0) < i) {
462 #endif
450 *statusret = errno; 463 *statusret = errno;
464 #ifndef _WIN32
451 close(fd); 465 close(fd);
466 #else
467 closesocket(fd);
468 #endif
452 return -1; 469 return -1;
453 } 470 }
454 471 #ifndef _WIN32
455 if (read(fd, buf, 2) < 2) { 472 if (read(fd, buf, 2) < 2) {
473 #else
474 if (recv(fd, buf, 2, 0) < 2) {
475 #endif
456 *statusret = errno; 476 *statusret = errno;
477 #ifndef _WIN32
457 close(fd); 478 close(fd);
479 #else
480 closesocket(fd);
481 #endif
458 return -1; 482 return -1;
459 } 483 }
460 484
461 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { 485 if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
462 *statusret = EINVAL; 486 *statusret = EINVAL;
487 #ifndef _WIN32
463 close(fd); 488 close(fd);
489 #else
490 closesocket(fd);
491 #endif
464 return -1; 492 return -1;
465 } 493 }
466 494
467 /* check if we're doing username authentication */ 495 /* check if we're doing username authentication */
468 if (buf[1] == 0x02) { 496 if (buf[1] == 0x02) {
469 i = aimutil_put8(buf, 0x01); /* version 1 */ 497 i = aimutil_put8(buf, 0x01); /* version 1 */
470 i += aimutil_put8(buf+i, strlen(sess->socksproxy.username)); 498 i += aimutil_put8(buf+i, strlen(sess->socksproxy.username));
471 i += aimutil_putstr(buf+i, sess->socksproxy.username, strlen(sess->socksproxy.username)); 499 i += aimutil_putstr(buf+i, sess->socksproxy.username, strlen(sess->socksproxy.username));
472 i += aimutil_put8(buf+i, strlen(sess->socksproxy.password)); 500 i += aimutil_put8(buf+i, strlen(sess->socksproxy.password));
473 i += aimutil_putstr(buf+i, sess->socksproxy.password, strlen(sess->socksproxy.password)); 501 i += aimutil_putstr(buf+i, sess->socksproxy.password, strlen(sess->socksproxy.password));
502 #ifndef _WIN32
474 if (write(fd, buf, i) < i) { 503 if (write(fd, buf, i) < i) {
504 #else
505 if (send(fd, buf, i, 0) < i) {
506 #endif
475 *statusret = errno; 507 *statusret = errno;
508 #ifndef _WIN32
476 close(fd); 509 close(fd);
510 #else
511 closesocket(fd);
512 #endif
477 return -1; 513 return -1;
478 } 514 }
515 #ifndef _WIN32
479 if (read(fd, buf, 2) < 2) { 516 if (read(fd, buf, 2) < 2) {
517 #else
518 if (recv(fd, buf, 2, 0) < 2) {
519 #endif
480 *statusret = errno; 520 *statusret = errno;
521 #ifndef _WIN32
481 close(fd); 522 close(fd);
523 #else
524 closesocket(fd);
525 #endif
482 return -1; 526 return -1;
483 } 527 }
484 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { 528 if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
485 *statusret = EINVAL; 529 *statusret = EINVAL;
530 #ifndef _WIN32
486 close(fd); 531 close(fd);
532 #else
533 closesocket(fd);
534 #endif
487 return -1; 535 return -1;
488 } 536 }
489 } 537 }
490 538
491 i = aimutil_put8(buf, 0x05); 539 i = aimutil_put8(buf, 0x05);
493 i += aimutil_put8(buf+i, 0x00); /* reserved */ 541 i += aimutil_put8(buf+i, 0x00); /* reserved */
494 i += aimutil_put8(buf+i, 0x03); /* address type: host name */ 542 i += aimutil_put8(buf+i, 0x03); /* address type: host name */
495 i += aimutil_put8(buf+i, strlen(host)); 543 i += aimutil_put8(buf+i, strlen(host));
496 i += aimutil_putstr(buf+i, host, strlen(host)); 544 i += aimutil_putstr(buf+i, host, strlen(host));
497 i += aimutil_put16(buf+i, port); 545 i += aimutil_put16(buf+i, port);
498 546 #ifndef _WIN32
499 if (write(fd, buf, i) < i) { 547 if (write(fd, buf, i) < i) {
548 #else
549 if (send(fd, buf, i, 0) < i) {
550 #endif
500 *statusret = errno; 551 *statusret = errno;
552 #ifndef _WIN32
501 close(fd); 553 close(fd);
554 #else
555 closesocket(fd);
556 #endif
502 return -1; 557 return -1;
503 } 558 }
559 #ifndef _WIN32
504 if (read(fd, buf, 10) < 10) { 560 if (read(fd, buf, 10) < 10) {
561 #else
562 if (recv(fd, buf, 10, 0) < 10) {
563 #endif
505 *statusret = errno; 564 *statusret = errno;
565 #ifndef _WIN32
506 close(fd); 566 close(fd);
567 #else
568 closesocket(fd);
569 #endif
507 return -1; 570 return -1;
508 } 571 }
509 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { 572 if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
510 *statusret = EINVAL; 573 *statusret = EINVAL;
574 #ifndef _WIN32
511 close(fd); 575 close(fd);
576 #else
577 closesocket(fd);
578 #endif
512 return -1; 579 return -1;
513 } 580 }
514 581
515 } else { /* connecting directly */ 582 } else { /* connecting directly */
516 struct sockaddr_in sa; 583 struct sockaddr_in sa;
517 struct hostent *hp; 584 struct hostent *hp;
518 585 #ifdef _WIN32
586 int imode = 1;
587 int w_errno = 0;
588 #endif
519 if (!(hp = gethostbyname(host))) { 589 if (!(hp = gethostbyname(host))) {
520 *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR); 590 *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
521 return -1; 591 return -1;
522 } 592 }
523 593
527 sa.sin_family = hp->h_addrtype; 597 sa.sin_family = hp->h_addrtype;
528 598
529 fd = socket(hp->h_addrtype, SOCK_STREAM, 0); 599 fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
530 600
531 if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT) 601 if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT)
602 #ifndef _WIN32
532 fcntl(fd, F_SETFL, O_NONBLOCK); /* XXX save flags */ 603 fcntl(fd, F_SETFL, O_NONBLOCK); /* XXX save flags */
533 604 #else
605 ioctlsocket(fd, FIONBIO, (unsigned long *)&imode);
606 #endif
534 if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { 607 if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
535 if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT) { 608 if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT) {
609 #ifndef _WIN32
536 if ((errno == EINPROGRESS) || (errno == EINTR)) { 610 if ((errno == EINPROGRESS) || (errno == EINTR)) {
611 #else
612 w_errno = WSAGetLastError();
613 if ((w_errno == WSAEINPROGRESS) || (w_errno == WSAEINTR)) {
614 #endif
537 if (statusret) 615 if (statusret)
538 *statusret |= AIM_CONN_STATUS_INPROGRESS; 616 *statusret |= AIM_CONN_STATUS_INPROGRESS;
539 return fd; 617 return fd;
540 } 618 }
541 } 619 }
620 #ifndef _WIN32
542 close(fd); 621 close(fd);
622 #else
623 closesocket(fd);
624 #endif
543 fd = -1; 625 fd = -1;
544 } 626 }
545 } 627 }
546 return fd; 628 return fd;
547 } 629 }
985 */ 1067 */
986 faim_export int aim_conn_completeconnect(aim_session_t *sess, aim_conn_t *conn) 1068 faim_export int aim_conn_completeconnect(aim_session_t *sess, aim_conn_t *conn)
987 { 1069 {
988 fd_set fds, wfds; 1070 fd_set fds, wfds;
989 struct timeval tv; 1071 struct timeval tv;
990 int res, error = ETIMEDOUT; 1072 int res;
1073 #ifndef _WIN32
1074 int error = ETIMEDOUT;
1075 #else
1076 int error = 0;
1077 #endif
991 aim_rxcallback_t userfunc; 1078 aim_rxcallback_t userfunc;
992 1079
993 if (!conn || (conn->fd == -1)) 1080 if (!conn || (conn->fd == -1))
994 return -1; 1081 return -1;
995 1082
1002 FD_SET(conn->fd, &wfds); 1089 FD_SET(conn->fd, &wfds);
1003 tv.tv_sec = 0; 1090 tv.tv_sec = 0;
1004 tv.tv_usec = 0; 1091 tv.tv_usec = 0;
1005 1092
1006 if ((res = select(conn->fd+1, &fds, &wfds, NULL, &tv)) == -1) { 1093 if ((res = select(conn->fd+1, &fds, &wfds, NULL, &tv)) == -1) {
1094 #ifndef _WIN32
1007 error = errno; 1095 error = errno;
1096 #else
1097 error = WSAGetLastError();
1098 #endif
1008 aim_conn_close(conn); 1099 aim_conn_close(conn);
1009 errno = error; 1100 errno = error;
1010 return -1; 1101 return -1;
1011 } else if (res == 0) { 1102 } else if (res == 0) {
1012 faimdprintf(sess, 0, "aim_conn_completeconnect: false alarm on %d\n", conn->fd); 1103 faimdprintf(sess, 0, "aim_conn_completeconnect: false alarm on %d\n", conn->fd);
1013 return 0; /* hasn't really completed yet... */ 1104 return 0; /* hasn't really completed yet... */
1014 } 1105 }
1015 1106
1016 if (FD_ISSET(conn->fd, &fds) || FD_ISSET(conn->fd, &wfds)) { 1107 if (FD_ISSET(conn->fd, &fds) || FD_ISSET(conn->fd, &wfds)) {
1017 int len = sizeof(error); 1108 int len = sizeof(error);
1018 1109 #ifndef _WIN32
1019 if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) 1110 if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
1020 error = errno; 1111 error = errno;
1112 #else
1113 if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) < 0)
1114 error = WSAGetLastError();
1115 #endif
1021 } 1116 }
1022 1117
1023 if (error) { 1118 if (error) {
1024 aim_conn_close(conn); 1119 aim_conn_close(conn);
1025 errno = error; 1120 errno = error;
1026 return -1; 1121 return -1;
1027 } 1122 }
1028 1123 #ifndef _WIN32
1029 fcntl(conn->fd, F_SETFL, 0); /* XXX should restore original flags */ 1124 fcntl(conn->fd, F_SETFL, 0); /* XXX should restore original flags */
1030 1125 #endif
1031 conn->status &= ~AIM_CONN_STATUS_INPROGRESS; 1126 conn->status &= ~AIM_CONN_STATUS_INPROGRESS;
1032 1127
1033 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE))) 1128 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE)))
1034 userfunc(sess, NULL, conn); 1129 userfunc(sess, NULL, conn);
1035 1130

mercurial