Changeset 10616


Ignore:
Timestamp:
May 1, 2010, 7:55:45 PM (8 years ago)
Author:
charles
Message:

(trunk libT) commit jch's patch for #2738: "fix rebinding of the IPv DHT socket"

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/tr-dht.c

    r10500 r10616  
    249249
    250250static int
    251 rebind_ipv6(int force)
     251rebind_ipv6(void)
    252252{
    253253    struct sockaddr_in6 sin6;
    254254    const unsigned char *ipv6 = tr_globalIPv6();
    255255    static unsigned char *last_bound = NULL;
    256     int rc;
    257 
    258     if(dht6_socket < 0)
     256    int s, rc;
     257    int one = 1;
     258
     259    /* We currently have no way to enable or disable IPv6 once the DHT has
     260       been initialised.  Oh, well. */
     261    if(dht6_socket < 0 || ipv6 == NULL) {
     262        if(last_bound) {
     263            free(last_bound);
     264            last_bound = NULL;
     265        }
    259266        return 0;
    260 
    261     if(!force &&
    262        ((ipv6 == NULL && last_bound == NULL) ||
    263         (ipv6 != NULL && last_bound != NULL &&
    264          memcmp(ipv6, last_bound, 16) == 0)))
     267    }
     268
     269    if(last_bound != NULL && memcmp(ipv6, last_bound, 16) == 0)
    265270        return 0;
     271
     272    s = socket(PF_INET6, SOCK_DGRAM, 0);
     273    if(s < 0)
     274        return -1;
     275
     276#ifdef IPV6_V6ONLY
     277        /* Since we always open an IPv4 socket on the same port, this
     278           shouldn't matter.  But I'm superstitious. */
     279        setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
     280#endif
    266281
    267282    memset(&sin6, 0, sizeof(sin6));
     
    270285        memcpy(&sin6.sin6_addr, ipv6, 16);
    271286    sin6.sin6_port = htons(dht_port);
    272     rc = bind(dht6_socket, (struct sockaddr*)&sin6, sizeof(sin6));
    273 
     287    rc = bind(s, (struct sockaddr*)&sin6, sizeof(sin6));
     288
     289    if(rc < 0)
     290        return -1;
     291
     292    if(dht6_socket < 0) {
     293        dht6_socket = s;
     294    } else {
     295        rc = dup2(s, dht6_socket);
     296        close(s);
     297        if(rc < 0)
     298            return -1;
     299    }
     300
     301    if(last_bound == NULL)
     302        last_bound = malloc(16);
    274303    if(last_bound)
    275         free(last_bound);
    276     last_bound = NULL;
    277 
    278     if(rc >= 0 && ipv6) {
    279         last_bound = malloc(16);
    280         if(last_bound)
    281             memcpy(last_bound, ipv6, 16);
    282     }
    283     return rc;
     304        memcpy(last_bound, ipv6, 16);
     305
     306    return 1;
    284307}
    285308
     
    319342        goto fail;
    320343
    321     if(tr_globalIPv6()) {
    322         int one = 1;
    323         dht6_socket = socket(PF_INET6, SOCK_DGRAM, 0);
    324         if(dht6_socket < 0)
    325             goto fail;
    326 
    327 #ifdef IPV6_V6ONLY
    328         /* Since we always open an IPv4 socket on the same port, this
    329            shouldn't matter.  But I'm superstitious. */
    330         setsockopt(dht6_socket, IPPROTO_IPV6, IPV6_V6ONLY,
    331                    &one, sizeof(one));
    332 #endif
    333 
    334         rebind_ipv6(1);
    335 
    336     }
     344    if(tr_globalIPv6())
     345        rebind_ipv6();
    337346
    338347    if( getenv( "TR_DHT_VERBOSE" ) != NULL )
     
    699708       avoids a system call. */
    700709    count++;
    701     if(count >= 128) {
    702         rebind_ipv6(0);
     710    if(count >= 20) {
     711        rebind_ipv6();
    703712        count = 0;
    704713    }
Note: See TracChangeset for help on using the changeset viewer.