NOEXPORT void connect_setup(CLI *c) {
    if(redirect(c)) { /* process "redirect" first */
        s_log(LOG_NOTICE, "Redirecting connection");
        /* c->connect_addr.addr may be allocated in protocol negotiations */
        str_free(c->connect_addr.addr);
        addrlist_dup(&c->connect_addr, &c->opt->redirect_addr);
        return;
    }

    /* check if the address was already set in protocol negotiations */
    /* used by the following protocols: CONNECT, SOCKS */
    if(c->connect_addr.num)
        return;

    /* transparent destination */
    if(c->opt->option.transparent_dst) {
        c->connect_addr.num=1;
        c->connect_addr.addr=str_alloc(sizeof(SOCKADDR_UNION));
        if(original_dst(c->local_rfd.fd, c->connect_addr.addr))
            throw_exception(c, 1);
        return;
    }

    /* default "connect" target */
    addrlist_dup(&c->connect_addr, &c->opt->connect_addr);
}
NOEXPORT void connect_setup(CLI *c) {
    if(redirect(c)) {  
        s_log(LOG_NOTICE, "Redirecting connection");
         
        str_free(c->connect_addr.addr);
        addrlist_dup(&c->connect_addr, &c->opt->redirect_addr);
        return;
    }

     
     
    if(c->connect_addr.num)
        return;

     
    if(c->opt->option.transparent_dst) {
        c->connect_addr.num=1;
        c->connect_addr.addr=str_alloc(sizeof(SOCKADDR_UNION));
        if(original_dst(c->local_rfd.fd, c->connect_addr.addr))
            throw_exception(c, 1);
        return;
    }

     
    addrlist_dup(&c->connect_addr, &c->opt->connect_addr);
}