/* connect remote host */ NOEXPORT int connect_remote(CLI *c) { int fd, ind_start, ind_try, ind_cur; setup_connect_addr(c); ind_start=c->connect_addr.cur; /* the race condition here can be safely ignored */ if(c->opt->failover==FAILOVER_RR) c->connect_addr.cur=(ind_start+1)%c->connect_addr.num; /* try to connect each host from the list */ for(ind_try=0; ind_try<c->connect_addr.num; ind_try++) { ind_cur=(ind_start+ind_try)%c->connect_addr.num; c->fd=s_socket(c->connect_addr.addr[ind_cur].sa.sa_family, SOCK_STREAM, 0, 1, "remote socket"); if(c->fd<0) longjmp(c->err, 1); local_bind(c); /* explicit local bind or transparent proxy */ if(s_connect(c, &c->connect_addr.addr[ind_cur], addr_len(&c->connect_addr.addr[ind_cur]))) { closesocket(c->fd); c->fd=-1; continue; /* next IP */ } print_bound_address(c); fd=c->fd; c->fd=-1; return fd; /* success! */ } longjmp(c->err, 1); return -1; /* some C compilers require a return value */ }
static int connect_remote(CLI *c) { /* connect remote host */ SOCKADDR_UNION addr; SOCKADDR_LIST resolved_list, *address_list; int fd, ind_try, ind_cur; /* setup address_list */ if(c->opt->option.delayed_lookup) { resolved_list.num=0; if(!name2addrlist(&resolved_list, c->opt->remote_address, DEFAULT_LOOPBACK)) { s_log(LOG_ERR, "No host resolved"); longjmp(c->err, 1); } address_list=&resolved_list; } else /* use pre-resolved addresses */ address_list=&c->opt->remote_addr; /* try to connect each host from the list */ for(ind_try=0; ind_try<address_list->num; ind_try++) { if(c->opt->failover==FAILOVER_RR) { ind_cur=address_list->cur; /* the race condition here can be safely ignored */ address_list->cur=(ind_cur+1)%address_list->num; } else { /* FAILOVER_PRIO */ ind_cur=ind_try; /* ignore address_list->cur */ } memcpy(&addr, address_list->addr+ind_cur, sizeof addr); c->fd=s_socket(addr.sa.sa_family, SOCK_STREAM, 0, 1, "remote socket"); if(c->fd<0) longjmp(c->err, 1); if(c->bind_addr.num) /* explicit local bind or transparent proxy */ local_bind(c); if(connect_blocking(c, &addr, addr_len(addr))) { closesocket(c->fd); c->fd=-1; continue; /* next IP */ } print_bound_address(c); fd=c->fd; c->fd=-1; return fd; /* success! */ } longjmp(c->err, 1); return -1; /* some C compilers require a return value */ }
static int connect_transparent(CLI *c) { /* connect the original dst */ SOCKADDR_UNION addr; socklen_t addrlen=sizeof addr; int retval; if(getsockopt(c->local_rfd.fd, SOL_IP, SO_ORIGINAL_DST, &addr, &addrlen)) { sockerror("setsockopt SO_ORIGINAL_DST"); longjmp(c->err, 1); } c->fd=s_socket(addr.sa.sa_family, SOCK_STREAM, 0, 1, "remote socket"); if(c->fd<0) longjmp(c->err, 1); if(c->bind_addr.num) /* explicit local bind or transparent proxy */ local_bind(c); if(connect_blocking(c, &addr, addr_len(addr))) longjmp(c->err, 1); /* socket closed on cleanup */ print_bound_address(c); retval=c->fd; c->fd=-1; return retval; /* success! */ }
static int connect_remote(CLI * c) { int fd, ind_try, ind_cur; SOCKADDR_LIST *remote_addr; remote_addr = dynamic_remote_addr(c); for (ind_try = 0; ind_try < remote_addr->num; ind_try++) { if (c->opt->failover == FAILOVER_RR) { ind_cur = remote_addr->cur; remote_addr->cur = (ind_cur + 1) % remote_addr->num; } else { ind_cur = ind_try; } c->fd = s_socket(remote_addr->addr[ind_cur].sa.sa_family, SOCK_STREAM, 0, 1, "remote socket"); if (c->fd < 0) longjmp(c->err, 1); local_bind(c); if (connect_blocking(c, &remote_addr->addr[ind_cur], addr_len(&remote_addr->addr[ind_cur]))) { closesocket(c->fd); c->fd = -1; continue; } print_bound_address(c); fd = c->fd; c->fd = -1; return fd; } longjmp(c->err, 1); return -1; }
/* connect remote host */ static int connect_remote(CLI *c) { int fd, ind_try, ind_cur; SOCKADDR_LIST *remote_addr; /* list of connect_blocking() targets */ remote_addr=dynamic_remote_addr(c); /* try to connect each host from the list */ for(ind_try=0; ind_try<remote_addr->num; ind_try++) { if(c->opt->failover==FAILOVER_RR) { ind_cur=remote_addr->cur; /* the race condition here can be safely ignored */ remote_addr->cur=(ind_cur+1)%remote_addr->num; } else { /* FAILOVER_PRIO */ ind_cur=ind_try; /* ignore remote_addr->cur */ } c->fd=s_socket(remote_addr->addr[ind_cur].sa.sa_family, SOCK_STREAM, 0, 1, "remote socket"); if(c->fd<0) longjmp(c->err, 1); local_bind(c); /* explicit local bind or transparent proxy */ if(connect_blocking(c, &remote_addr->addr[ind_cur], addr_len(&remote_addr->addr[ind_cur]))) { closesocket(c->fd); c->fd=-1; continue; /* next IP */ } print_bound_address(c); fd=c->fd; c->fd=-1; return fd; /* success! */ } longjmp(c->err, 1); return -1; /* some C compilers require a return value */ }