Changeset 701

Show
Ignore:
Timestamp:
02/18/08 09:22:47 (9 months ago)
Author:
dormando
Message:

Support multiple interfaces returned by IPv6 interfaces. By Brian Aker <brian@tangent.org>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/server/memcached.c

    r700 r701  
    6565static void drive_machine(conn *c); 
    6666static int new_socket(struct addrinfo *ai); 
    67 static int server_socket(const int port, const bool is_udp); 
     67static int *server_socket(const int port, const bool is_udp, int *count); 
    6868static int try_read_command(conn *c); 
    6969static int try_read_network(conn *c); 
     
    9595                              (to avoid 64 bit time_t) */ 
    9696 
    97 void pre_gdb(void); 
    9897static void conn_free(conn *c); 
    9998 
     
    106105static int delcurr; 
    107106static int deltotal; 
    108 static conn *listen_conn
     107static conn *listen_conn = NULL
    109108static struct event_base *main_base; 
    110109 
     
    252251    freecurr = 0; 
    253252    if ((freeconns = (conn **)malloc(sizeof(conn *) * freetotal)) == NULL) { 
    254         perror("malloc()"); 
     253        fprintf(stderr, "malloc()\n"); 
    255254    } 
    256255    return; 
     
    300299    if (NULL == c) { 
    301300        if (!(c = (conn *)malloc(sizeof(conn)))) { 
    302             perror("malloc()"); 
     301            fprintf(stderr, "malloc()\n"); 
    303302            return NULL; 
    304303        } 
     
    334333            if (c->msglist != 0) free(c->msglist); 
    335334            free(c); 
    336             perror("malloc()"); 
     335            fprintf(stderr, "malloc()\n"); 
    337336            return NULL; 
    338337        } 
     
    382381            conn_free(c); 
    383382        } 
     383        perror("event_add"); 
    384384        return NULL; 
    385385    } 
     
    559559    freesuffix = (char **)malloc( sizeof(char *) * freesuffixtotal ); 
    560560    if (freesuffix == NULL) { 
    561         perror("malloc()"); 
     561        fprintf(stderr, "malloc()\n"); 
    562562    } 
    563563    return; 
     
    19651965 */ 
    19661966void accept_new_conns(const bool do_accept) { 
     1967    conn *next; 
     1968 
    19671969    if (! is_listen_thread()) 
    19681970        return; 
    1969     if (do_accept) { 
    1970         update_event(listen_conn, EV_READ | EV_PERSIST); 
    1971         if (listen(listen_conn->sfd, 1024) != 0) { 
    1972             perror("listen"); 
    1973         } 
    1974     } 
    1975     else { 
    1976         update_event(listen_conn, 0); 
    1977         if (listen(listen_conn->sfd, 0) != 0) { 
    1978             perror("listen"); 
    1979         } 
    1980     } 
     1971 
     1972    for (next = listen_conn; next; next = next->next) { 
     1973        if (do_accept) { 
     1974            update_event(next, EV_READ | EV_PERSIST); 
     1975            if (listen(next->sfd, 1024) != 0) { 
     1976                perror("listen"); 
     1977            } 
     1978        } 
     1979        else { 
     1980            update_event(next, 0); 
     1981            if (listen(next->sfd, 0) != 0) { 
     1982                perror("listen"); 
     1983            } 
     1984        } 
     1985  } 
    19811986} 
    19821987 
     
    23482353 
    23492354 
    2350 static int server_socket(const int port, const bool is_udp) { 
     2355static int *server_socket(const int port, const bool is_udp, int *count) { 
    23512356    int sfd; 
     2357    int *sfd_list; 
     2358    int *sfd_ptr; 
    23522359    struct linger ling = {0, 0}; 
    23532360    struct addrinfo *ai; 
     2361    struct addrinfo *next; 
    23542362    struct addrinfo hints; 
    23552363    char port_buf[NI_MAXSERV]; 
    23562364    int error; 
     2365    int success = 0; 
    23572366 
    23582367    int flags =1; 
     
    23832392        perror("getaddrinfo()"); 
    23842393 
    2385       return -1; 
    2386     } 
    2387  
    2388     if ((sfd = new_socket(ai)) == -1) { 
    2389         freeaddrinfo(ai); 
    2390         return -1; 
    2391     } 
    2392  
    2393     setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags)); 
    2394     if (is_udp) { 
    2395         maximize_sndbuf(sfd); 
    2396     } else { 
    2397         setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags)); 
    2398         setsockopt(sfd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling)); 
    2399         setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)); 
    2400     } 
    2401  
    2402     if (bind(sfd, ai->ai_addr, ai->ai_addrlen) == -1) { 
    2403         perror("bind()"); 
    2404         close(sfd); 
    2405         freeaddrinfo(ai); 
    2406         return -1; 
    2407     } 
    2408     if (!is_udp && listen(sfd, 1024) == -1) { 
    2409         perror("listen()"); 
    2410         close(sfd); 
    2411         freeaddrinfo(ai); 
    2412         return -1; 
     2394      return NULL; 
     2395    } 
     2396 
     2397    for (*count= 1, next= ai; next->ai_next; next= next->ai_next, (*count)++); 
     2398 
     2399    sfd_list= (int *)calloc(*count, sizeof(int)); 
     2400    if (sfd_list == NULL) { 
     2401        fprintf(stderr, "calloc()\n"); 
     2402        return NULL; 
     2403    } 
     2404    memset(sfd_list, -1, sizeof(int) * (*count)); 
     2405 
     2406    for (sfd_ptr= sfd_list, next= ai; next; next= next->ai_next, sfd_ptr++) { 
     2407        if ((sfd = new_socket(next)) == -1) { 
     2408            free(sfd_list); 
     2409            freeaddrinfo(ai); 
     2410            return NULL; 
     2411        } 
     2412 
     2413        setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags)); 
     2414        if (is_udp) { 
     2415            maximize_sndbuf(sfd); 
     2416        } else { 
     2417            setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags)); 
     2418            setsockopt(sfd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling)); 
     2419            setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)); 
     2420        } 
     2421 
     2422        if (bind(sfd, next->ai_addr, next->ai_addrlen) == -1) { 
     2423            if (errno != EADDRINUSE) { 
     2424                perror("bind()"); 
     2425                /* If we are not at the first element, loop back and close all sockets */ 
     2426                if (sfd_ptr != sfd_list) { 
     2427                    do { 
     2428                        --sfd_ptr; 
     2429                        close(*sfd_ptr); 
     2430                    } while (sfd_ptr != sfd_list); 
     2431                } 
     2432                close(sfd); 
     2433                freeaddrinfo(ai); 
     2434                free(sfd_list); 
     2435                return NULL; 
     2436            } 
     2437            close(sfd); 
     2438            *sfd_ptr= -1; 
     2439        } else { 
     2440          success++; 
     2441          *sfd_ptr= sfd; 
     2442          if (!is_udp && listen(sfd, 1024) == -1) { 
     2443              perror("listen()"); 
     2444                if (sfd_ptr != sfd_list) { 
     2445                    do { 
     2446                        --sfd_ptr; 
     2447                        close(*sfd_ptr); 
     2448                    } while (sfd_ptr != sfd_list); 
     2449                } 
     2450              close(sfd); 
     2451              freeaddrinfo(ai); 
     2452              free(sfd_list); 
     2453              return NULL; 
     2454          } 
     2455      } 
    24132456    } 
    24142457 
    24152458    freeaddrinfo(ai); 
    24162459 
    2417     return sfd; 
     2460    if (success == 0) { 
     2461        free(sfd_list); 
     2462        return NULL; 
     2463    } 
     2464 
     2465    return sfd_list; 
    24182466} 
    24192467 
     
    24362484} 
    24372485 
    2438 static int server_socket_unix(const char *path, int access_mask) { 
     2486static int *server_socket_unix(const char *path, int access_mask) { 
    24392487    int sfd; 
     2488    int *sfd_list; 
    24402489    struct linger ling = {0, 0}; 
    24412490    struct sockaddr_un addr; 
     
    24452494 
    24462495    if (!path) { 
    2447         return -1
     2496        return NULL
    24482497    } 
    24492498 
    24502499    if ((sfd = new_socket_unix()) == -1) { 
    2451         return -1; 
    2452     } 
     2500        return NULL; 
     2501    } 
     2502 
     2503    /* 
     2504      When UNIX domain sockets get refactored, this will go away. 
     2505      For now we know there is just one socket. 
     2506    */ 
     2507    sfd_list= (int *)calloc(1, sizeof(int)); 
     2508    if (sfd_list == NULL) { 
     2509        fprintf(stderr, "calloc()\n"); 
     2510        return NULL; 
     2511    } 
     2512    memset(sfd_list, -1, sizeof(int) * 1); 
    24532513 
    24542514    /* 
     
    24762536        perror("bind()"); 
    24772537        close(sfd); 
     2538        free(sfd_list); 
    24782539        umask(old_umask); 
    2479         return -1
     2540        return NULL
    24802541    } 
    24812542    umask(old_umask); 
     
    24832544        perror("listen()"); 
    24842545        close(sfd); 
    2485         return -1; 
    2486     } 
    2487     return sfd; 
    2488 
    2489  
    2490 /* listening socket */ 
    2491 static int l_socket = 0; 
    2492  
    2493 /* udp socket */ 
    2494 static int u_socket = -1; 
    2495  
    2496 /* invoke right before gdb is called, on assert */ 
    2497 void pre_gdb(void) { 
    2498     int i; 
    2499     if (l_socket > -1) close(l_socket); 
    2500     if (u_socket > -1) close(u_socket); 
    2501     for (i = 3; i <= 500; i++) close(i); /* so lame */ 
    2502     kill(getpid(), SIGABRT); 
     2546        free(sfd_list); 
     2547        return NULL; 
     2548    } 
     2549 
     2550    *sfd_list= sfd; 
     2551 
     2552    return sfd_list; 
    25032553} 
    25042554 
     
    27152765int main (int argc, char **argv) { 
    27162766    int c; 
     2767    int x; 
    27172768    bool lock_memory = false; 
    27182769    bool daemonize = false; 
     
    27232774    struct sigaction sa; 
    27242775    struct rlimit rlim; 
     2776    /* listening socket */ 
     2777    static int *l_socket = NULL; 
     2778    static int l_socket_count = 0; 
     2779 
     2780    /* udp socket */ 
     2781    static int *u_socket = NULL; 
     2782    static int u_socket_count = 0; 
    27252783 
    27262784    /* handle SIGINT */ 
     
    28792937    /* create the listening socket and bind it */ 
    28802938    if (settings.socketpath == NULL) { 
    2881         l_socket = server_socket(settings.port, 0); 
    2882         if (l_socket == -1) { 
     2939        l_socket = server_socket(settings.port, 0, &l_socket_count); 
     2940        if (l_socket == NULL) { 
    28832941            fprintf(stderr, "failed to listen\n"); 
    28842942            exit(EXIT_FAILURE); 
     
    28882946    if (settings.udpport > 0 && settings.socketpath == NULL) { 
    28892947        /* create the UDP listening socket and bind it */ 
    2890         u_socket = server_socket(settings.udpport, 1); 
    2891         if (u_socket == -1) { 
     2948        u_socket = server_socket(settings.udpport, 1, &u_socket_count); 
     2949        if (u_socket == NULL) { 
    28922950            fprintf(stderr, "failed to listen on UDP port %d\n", settings.udpport); 
    28932951            exit(EXIT_FAILURE); 
     
    29272985    if (settings.socketpath != NULL) { 
    29282986        l_socket = server_socket_unix(settings.socketpath,settings.access); 
    2929         if (l_socket == -1) { 
    2930             fprintf(stderr, "failed to listen\n"); 
    2931             exit(EXIT_FAILURE); 
    2932         } 
     2987        if (l_socket == NULL) { 
     2988          fprintf(stderr, "failed to listen\n"); 
     2989          exit(EXIT_FAILURE); 
     2990        } 
     2991        /* We only support one of these, so whe know the count */ 
     2992        l_socket_count = 1; 
    29332993    } 
    29342994 
     
    29793039    } 
    29803040    /* create the initial listening connection */ 
    2981     if (!(listen_conn = conn_new(l_socket, conn_listening, 
    2982                                  EV_READ | EV_PERSIST, 1, false, main_base))) { 
    2983         fprintf(stderr, "failed to create listening connection"); 
    2984         exit(EXIT_FAILURE); 
     3041    int *l_socket_ptr; 
     3042    conn *next = NULL; 
     3043    for (l_socket_ptr= l_socket, x = 0; x < l_socket_count; l_socket_ptr++, x++) { 
     3044        conn *listen_conn_add; 
     3045        if (*l_socket_ptr > -1 ) { 
     3046            if (!(listen_conn_add = conn_new(*l_socket_ptr, conn_listening, 
     3047                                             EV_READ | EV_PERSIST, 1, false, main_base))) { 
     3048                fprintf(stderr, "failed to create listening connection\n"); 
     3049                exit(EXIT_FAILURE); 
     3050            } 
     3051 
     3052            if (listen_conn == NULL) { 
     3053                next = listen_conn = listen_conn_add; 
     3054            } else { 
     3055                next->next= listen_conn_add; 
     3056            } 
     3057        } 
    29853058    } 
    29863059    /* start up worker threads if MT mode */ 
     
    30013074    delete_handler(0, 0, 0); /* sets up the event */ 
    30023075    /* create the initial listening udp connection, monitored on all threads */ 
    3003     if (u_socket > -1) { 
     3076    if (u_socket) { 
    30043077        for (c = 0; c < settings.num_threads; c++) { 
    30053078            /* this is guaranteed to hit all threads because we round-robin */ 
    3006             dispatch_conn_new(u_socket, conn_read, EV_READ | EV_PERSIST, 
     3079            dispatch_conn_new(*u_socket, conn_read, EV_READ | EV_PERSIST, 
    30073080                              UDP_READ_BUFFER_SIZE, 1); 
    30083081        } 
     
    30163089    if (settings.inter) 
    30173090      free(settings.inter); 
     3091    if (l_socket) 
     3092      free(l_socket); 
     3093    if (u_socket) 
     3094      free(u_socket); 
    30183095 
    30193096    return 0; 
  • trunk/server/memcached.h

    r700 r701  
    151151#define NREAD_CAS 6 
    152152 
    153 typedef struct { 
     153typedef struct conn conn; 
     154struct conn { 
    154155    int    sfd; 
    155156    int    state; 
     
    220221                         a managed instance. -1 (_not_ 0) means invalid. */ 
    221222    int    gen;       /* generation requested for the bucket */ 
    222 } conn; 
     223    conn   *next;     /* Used for generating a list of conn structures */ 
     224}; 
    223225 
    224226/* number of virtual buckets for a managed instance */ 
     
    227229/* current time of day (updated periodically) */ 
    228230extern volatile rel_time_t current_time; 
    229  
    230 /* temporary hack */ 
    231 /* #define assert(x) if(!(x)) { printf("assert failure: %s\n", #x); pre_gdb(); } 
    232    void pre_gdb (); */ 
    233231 
    234232/* 
  • trunk/server/t/lib/MemcachedTest.pm

    r641 r701  
    143143 
    144144sub new_memcached { 
    145     my $args = shift || ""
    146     my $port = free_port(); 
     145    my ($args, $passed_port) = @_
     146    my $port = $passed_port || free_port(); 
    147147    my $udpport = free_port("udp"); 
    148148    $args .= " -p $port";