Show
Ignore:
Timestamp:
03/01/08 02:43:28 (21 months ago)
Author:
dsallings
Message:

Auto-discover the protocol being spoken on a per-connection basis.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/binary/server/memcached.c

    r731 r732  
    307307            rv="ascii-udp"; 
    308308            break; 
     309        case negotiating_prot: 
     310            rv="auto-negotiate"; 
     311            break; 
    309312    } 
    310313    return rv; 
     
    380383        } else if (prot == ascii_prot) { 
    381384            fprintf(stderr, "<%d new ascii client connection\n", sfd); 
     385        } else if (prot == negotiating_prot) { 
     386            fprintf(stderr, "<%d new auto-negotiating client connection\n", sfd); 
    382387        } else { 
    383388            fprintf(stderr, "<%d new unknown (%d) client connection\n", 
     
    515520        case binary_prot: 
    516521            rv=conn_bin_init; 
     522            break; 
     523        case negotiating_prot: 
     524            rv=conn_negotiate; 
    517525            break; 
    518526        default: 
     
    13661374} 
    13671375 
     1376static void reinit_bin_connection(conn *c) { 
     1377    if (settings.verbose > 0) 
     1378        fprintf(stderr, "*** Reinitializing binary connection.\n"); 
     1379    c->rlbytes = MIN_BIN_PKT_LENGTH; 
     1380    c->write_and_go = conn_bin_init; 
     1381    c->cmd = -1; 
     1382    c->substate = bin_no_state; 
     1383    c->rbytes = c->wbytes = 0; 
     1384    c->ritem = (char*)c->bin_header; 
     1385    c->rcurr = c->rbuf; 
     1386    c->wcurr = c->wbuf; 
     1387    conn_shrink(c); 
     1388    conn_set_state(c, conn_nread); 
     1389} 
     1390 
     1391/* These do the initial protocol switch.  At this point, we should've read 
     1392 * exactly one byte, and must treat that byte as the beginning of a command. */ 
     1393static void setup_bin_protocol(conn *c) { 
     1394    char *loc = (char*)c->bin_header; 
     1395    if (settings.verbose > 0) 
     1396        fprintf(stderr, "Negotiated protocol as binary.\n"); 
     1397 
     1398    c->protocol = binary_prot; 
     1399    reinit_bin_connection(c); 
     1400    /* Emulate a read of the first byte */ 
     1401    c->ritem[0] = c->rbuf[0]; 
     1402    c->ritem++; 
     1403    c->rlbytes--; 
     1404} 
     1405 
     1406static void setup_ascii_protocol(conn *c) { 
     1407    if (settings.verbose > 0) 
     1408        fprintf(stderr, "Negotiated protocol as ascii.\n"); 
     1409    c->protocol = ascii_prot; 
     1410 
     1411    /* We've already got the first letter of the command, so pretend like we 
     1412     * Did a single byte read from try_read_command */ 
     1413    c->rcurr=c->rbuf; 
     1414    c->rbytes=1; 
     1415    conn_set_state(c, conn_read); 
     1416} 
     1417 
    13681418static void complete_nread(conn *c) { 
    13691419    assert(c != NULL); 
     
    13731423    } else if(c->protocol == binary_prot) { 
    13741424        complete_nread_binary(c); 
     1425    } else if(c->protocol == negotiating_prot) { 
     1426        /* The first byte is either BIN_REQ_MAGIC, or we're speaking ascii */ 
     1427        if ((c->rbuf[0] & 0xff) == BIN_REQ_MAGIC) 
     1428            setup_bin_protocol(c); 
     1429        else 
     1430            setup_ascii_protocol(c); 
    13751431    } else { 
    13761432        assert(0); /* XXX:  Invalid case.  Should probably do more here. */ 
     
    27102766            break; 
    27112767 
     2768        case conn_negotiate: 
     2769            if (settings.verbose > 0) 
     2770                fprintf(stderr, "Negotiating protocol for a new connection\n"); 
     2771            c->rlbytes = 1; 
     2772            c->ritem = c->rbuf; 
     2773            c->rcurr = c->rbuf; 
     2774            c->wcurr = c->wbuf; 
     2775            conn_set_state(c, conn_nread); 
     2776            break; 
     2777 
    27122778        case conn_read: 
    27132779            if (try_read_command(c) != 0) { 
     
    27282794 
    27292795        case conn_bin_init: /* Reinitialize a binary connection */ 
    2730             c->rlbytes = MIN_BIN_PKT_LENGTH; 
    2731             c->write_and_go = conn_bin_init; 
    2732             c->cmd = -1; 
    2733             c->substate = bin_no_state; 
    2734             c->rbytes = c->wbytes = 0; 
    2735             c->wcurr = c->wbuf; 
    2736             c->rcurr = c->rbuf; 
    2737             c->ritem = (char*)c->bin_header; 
    2738             conn_set_state(c, conn_nread); 
    2739             conn_shrink(c); 
     2796            reinit_bin_connection(c); 
    27402797            break; 
    27412798 
     
    37283785        int udp_port; 
    37293786 
    3730         if (server_socket(settings.port, ascii_prot)) { 
     3787        if (server_socket(settings.port, negotiating_prot)) { 
    37313788            fprintf(stderr, "failed to listen\n"); 
    37323789            exit(EXIT_FAILURE);