| 648 | #endif |
| 649 | |
| 650 | int doconnect(struct clientparam * param){ |
| 651 | SASIZETYPE size; |
| 652 | |
| 653 | |
| 654 | if (*SAFAMILY(¶m->sincr) == *SAFAMILY(¶m->req) && !memcmp(SAADDR(¶m->sincr), SAADDR(¶m->req), SAADDRLEN(¶m->req)) && |
| 655 | *SAPORT(¶m->sincr) == *SAPORT(¶m->req)) return 519; |
| 656 | |
| 657 | if (param->operation == ADMIN || param->operation == DNSRESOLVE || param->operation == BIND || param->operation == UDPASSOC) |
| 658 | return 0; |
| 659 | if (param->remsock != INVALID_SOCKET){ |
| 660 | size = sizeof(param->sinsr); |
| 661 | if(so._getpeername(param->remsock, (struct sockaddr *)¶m->sinsr, &size)==-1) {return (15);} |
| 662 | } |
| 663 | else { |
| 664 | struct linger lg = {1,conf.timeouts[SINGLEBYTE_S]}; |
| 665 | |
| 666 | if(SAISNULL(¶m->sinsr)){ |
| 667 | if(SAISNULL(¶m->req)) { |
| 668 | return 100; |
| 669 | } |
| 670 | *SAFAMILY(¶m->sinsr) = *SAFAMILY(¶m->req); |
| 671 | memcpy(SAADDR(¶m->sinsr), SAADDR(¶m->req), SAADDRLEN(¶m->req)); |
| 672 | } |
| 673 | if(!*SAPORT(¶m->sinsr))*SAPORT(¶m->sinsr) = *SAPORT(¶m->req); |
| 674 | if ((param->remsock=so._socket(SASOCK(¶m->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);} |
| 675 | so._setsockopt(param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg)); |
| 676 | #ifdef REUSE |
| 677 | { |
| 678 | int opt; |
| 679 | |
| 680 | #ifdef SO_REUSEADDR |
| 681 | opt = 1; |
| 682 | so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)); |
| 683 | #endif |
| 684 | #ifdef SO_REUSEPORT |
| 685 | opt = 1; |
| 686 | so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int)); |
| 687 | #endif |
| 688 | } |
| 689 | #endif |
| 690 | |
| 691 | if(SAISNULL(¶m->sinsl)){ |
| 692 | #ifndef NOIPV6 |
| 693 | if(*SAFAMILY(¶m->sinsr) == AF_INET6) param->sinsl = param->srv->extsa6; |
| 694 | else |
| 695 | #endif |
| 696 | param->sinsl = param->srv->extsa; |
| 697 | } |
| 698 | *SAPORT(¶m->sinsl) = 0; |
| 699 | if(so._bind(param->remsock, (struct sockaddr*)¶m->sinsl, SASIZE(¶m->sinsl))==-1) { |
| 700 | return 12; |
| 701 | } |
| 702 | |
| 703 | if(param->operation >= 256 || (param->operation & CONNECT)){ |
| 704 | #ifdef _WIN32 |
| 705 | unsigned long ul = 1; |
| 706 | #endif |
| 707 | if(so._connect(param->remsock,(struct sockaddr *)¶m->sinsr,SASIZE(¶m->sinsr))) { |