Annotation of embedaddon/nginx/src/http/ngx_http_upstream_round_robin.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (C) Igor Sysoev
                      4:  * Copyright (C) Nginx, Inc.
                      5:  */
                      6: 
                      7: 
                      8: #include <ngx_config.h>
                      9: #include <ngx_core.h>
                     10: #include <ngx_http.h>
                     11: 
                     12: 
                     13: static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer(
                     14:     ngx_http_upstream_rr_peer_data_t *rrp);
                     15: 
                     16: #if (NGX_HTTP_SSL)
                     17: 
                     18: static ngx_int_t ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc,
                     19:     void *data);
                     20: static void ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc,
                     21:     void *data);
                     22: 
                     23: #endif
                     24: 
                     25: 
                     26: ngx_int_t
                     27: ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
                     28:     ngx_http_upstream_srv_conf_t *us)
                     29: {
                     30:     ngx_url_t                      u;
                     31:     ngx_uint_t                     i, j, n, w;
                     32:     ngx_http_upstream_server_t    *server;
                     33:     ngx_http_upstream_rr_peers_t  *peers, *backup;
                     34: 
                     35:     us->peer.init = ngx_http_upstream_init_round_robin_peer;
                     36: 
                     37:     if (us->servers) {
                     38:         server = us->servers->elts;
                     39: 
                     40:         n = 0;
                     41:         w = 0;
                     42: 
                     43:         for (i = 0; i < us->servers->nelts; i++) {
                     44:             if (server[i].backup) {
                     45:                 continue;
                     46:             }
                     47: 
                     48:             n += server[i].naddrs;
                     49:             w += server[i].naddrs * server[i].weight;
                     50:         }
                     51: 
                     52:         if (n == 0) {
                     53:             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                     54:                           "no servers in upstream \"%V\" in %s:%ui",
                     55:                           &us->host, us->file_name, us->line);
                     56:             return NGX_ERROR;
                     57:         }
                     58: 
                     59:         peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
                     60:                               + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
                     61:         if (peers == NULL) {
                     62:             return NGX_ERROR;
                     63:         }
                     64: 
                     65:         peers->single = (n == 1);
                     66:         peers->number = n;
                     67:         peers->weighted = (w != n);
                     68:         peers->total_weight = w;
                     69:         peers->name = &us->host;
                     70: 
                     71:         n = 0;
                     72: 
                     73:         for (i = 0; i < us->servers->nelts; i++) {
                     74:             for (j = 0; j < server[i].naddrs; j++) {
                     75:                 if (server[i].backup) {
                     76:                     continue;
                     77:                 }
                     78: 
                     79:                 peers->peer[n].sockaddr = server[i].addrs[j].sockaddr;
                     80:                 peers->peer[n].socklen = server[i].addrs[j].socklen;
                     81:                 peers->peer[n].name = server[i].addrs[j].name;
                     82:                 peers->peer[n].max_fails = server[i].max_fails;
                     83:                 peers->peer[n].fail_timeout = server[i].fail_timeout;
                     84:                 peers->peer[n].down = server[i].down;
                     85:                 peers->peer[n].weight = server[i].weight;
                     86:                 peers->peer[n].effective_weight = server[i].weight;
                     87:                 peers->peer[n].current_weight = 0;
                     88:                 n++;
                     89:             }
                     90:         }
                     91: 
                     92:         us->peer.data = peers;
                     93: 
                     94:         /* backup servers */
                     95: 
                     96:         n = 0;
                     97:         w = 0;
                     98: 
                     99:         for (i = 0; i < us->servers->nelts; i++) {
                    100:             if (!server[i].backup) {
                    101:                 continue;
                    102:             }
                    103: 
                    104:             n += server[i].naddrs;
                    105:             w += server[i].naddrs * server[i].weight;
                    106:         }
                    107: 
                    108:         if (n == 0) {
                    109:             return NGX_OK;
                    110:         }
                    111: 
                    112:         backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
                    113:                               + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
                    114:         if (backup == NULL) {
                    115:             return NGX_ERROR;
                    116:         }
                    117: 
                    118:         peers->single = 0;
                    119:         backup->single = 0;
                    120:         backup->number = n;
                    121:         backup->weighted = (w != n);
                    122:         backup->total_weight = w;
                    123:         backup->name = &us->host;
                    124: 
                    125:         n = 0;
                    126: 
                    127:         for (i = 0; i < us->servers->nelts; i++) {
                    128:             for (j = 0; j < server[i].naddrs; j++) {
                    129:                 if (!server[i].backup) {
                    130:                     continue;
                    131:                 }
                    132: 
                    133:                 backup->peer[n].sockaddr = server[i].addrs[j].sockaddr;
                    134:                 backup->peer[n].socklen = server[i].addrs[j].socklen;
                    135:                 backup->peer[n].name = server[i].addrs[j].name;
                    136:                 backup->peer[n].weight = server[i].weight;
                    137:                 backup->peer[n].effective_weight = server[i].weight;
                    138:                 backup->peer[n].current_weight = 0;
                    139:                 backup->peer[n].max_fails = server[i].max_fails;
                    140:                 backup->peer[n].fail_timeout = server[i].fail_timeout;
                    141:                 backup->peer[n].down = server[i].down;
                    142:                 n++;
                    143:             }
                    144:         }
                    145: 
                    146:         peers->next = backup;
                    147: 
                    148:         return NGX_OK;
                    149:     }
                    150: 
                    151: 
                    152:     /* an upstream implicitly defined by proxy_pass, etc. */
                    153: 
                    154:     if (us->port == 0) {
                    155:         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                    156:                       "no port in upstream \"%V\" in %s:%ui",
                    157:                       &us->host, us->file_name, us->line);
                    158:         return NGX_ERROR;
                    159:     }
                    160: 
                    161:     ngx_memzero(&u, sizeof(ngx_url_t));
                    162: 
                    163:     u.host = us->host;
                    164:     u.port = us->port;
                    165: 
                    166:     if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
                    167:         if (u.err) {
                    168:             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                    169:                           "%s in upstream \"%V\" in %s:%ui",
                    170:                           u.err, &us->host, us->file_name, us->line);
                    171:         }
                    172: 
                    173:         return NGX_ERROR;
                    174:     }
                    175: 
                    176:     n = u.naddrs;
                    177: 
                    178:     peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
                    179:                               + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
                    180:     if (peers == NULL) {
                    181:         return NGX_ERROR;
                    182:     }
                    183: 
                    184:     peers->single = (n == 1);
                    185:     peers->number = n;
                    186:     peers->weighted = 0;
                    187:     peers->total_weight = n;
                    188:     peers->name = &us->host;
                    189: 
                    190:     for (i = 0; i < u.naddrs; i++) {
                    191:         peers->peer[i].sockaddr = u.addrs[i].sockaddr;
                    192:         peers->peer[i].socklen = u.addrs[i].socklen;
                    193:         peers->peer[i].name = u.addrs[i].name;
                    194:         peers->peer[i].weight = 1;
                    195:         peers->peer[i].effective_weight = 1;
                    196:         peers->peer[i].current_weight = 0;
                    197:         peers->peer[i].max_fails = 1;
                    198:         peers->peer[i].fail_timeout = 10;
                    199:     }
                    200: 
                    201:     us->peer.data = peers;
                    202: 
                    203:     /* implicitly defined upstream has no backup servers */
                    204: 
                    205:     return NGX_OK;
                    206: }
                    207: 
                    208: 
                    209: ngx_int_t
                    210: ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
                    211:     ngx_http_upstream_srv_conf_t *us)
                    212: {
                    213:     ngx_uint_t                         n;
                    214:     ngx_http_upstream_rr_peer_data_t  *rrp;
                    215: 
                    216:     rrp = r->upstream->peer.data;
                    217: 
                    218:     if (rrp == NULL) {
                    219:         rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t));
                    220:         if (rrp == NULL) {
                    221:             return NGX_ERROR;
                    222:         }
                    223: 
                    224:         r->upstream->peer.data = rrp;
                    225:     }
                    226: 
                    227:     rrp->peers = us->peer.data;
                    228:     rrp->current = 0;
                    229: 
                    230:     n = rrp->peers->number;
                    231: 
                    232:     if (rrp->peers->next && rrp->peers->next->number > n) {
                    233:         n = rrp->peers->next->number;
                    234:     }
                    235: 
                    236:     if (n <= 8 * sizeof(uintptr_t)) {
                    237:         rrp->tried = &rrp->data;
                    238:         rrp->data = 0;
                    239: 
                    240:     } else {
                    241:         n = (n + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t));
                    242: 
                    243:         rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t));
                    244:         if (rrp->tried == NULL) {
                    245:             return NGX_ERROR;
                    246:         }
                    247:     }
                    248: 
                    249:     r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer;
                    250:     r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
                    251:     r->upstream->peer.tries = rrp->peers->number;
                    252: #if (NGX_HTTP_SSL)
                    253:     r->upstream->peer.set_session =
                    254:                                ngx_http_upstream_set_round_robin_peer_session;
                    255:     r->upstream->peer.save_session =
                    256:                                ngx_http_upstream_save_round_robin_peer_session;
                    257: #endif
                    258: 
                    259:     return NGX_OK;
                    260: }
                    261: 
                    262: 
                    263: ngx_int_t
                    264: ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
                    265:     ngx_http_upstream_resolved_t *ur)
                    266: {
                    267:     u_char                            *p;
                    268:     size_t                             len;
                    269:     ngx_uint_t                         i, n;
                    270:     struct sockaddr_in                *sin;
                    271:     ngx_http_upstream_rr_peers_t      *peers;
                    272:     ngx_http_upstream_rr_peer_data_t  *rrp;
                    273: 
                    274:     rrp = r->upstream->peer.data;
                    275: 
                    276:     if (rrp == NULL) {
                    277:         rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t));
                    278:         if (rrp == NULL) {
                    279:             return NGX_ERROR;
                    280:         }
                    281: 
                    282:         r->upstream->peer.data = rrp;
                    283:     }
                    284: 
                    285:     peers = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_rr_peers_t)
                    286:                      + sizeof(ngx_http_upstream_rr_peer_t) * (ur->naddrs - 1));
                    287:     if (peers == NULL) {
                    288:         return NGX_ERROR;
                    289:     }
                    290: 
                    291:     peers->single = (ur->naddrs == 1);
                    292:     peers->number = ur->naddrs;
                    293:     peers->name = &ur->host;
                    294: 
                    295:     if (ur->sockaddr) {
                    296:         peers->peer[0].sockaddr = ur->sockaddr;
                    297:         peers->peer[0].socklen = ur->socklen;
                    298:         peers->peer[0].name = ur->host;
                    299:         peers->peer[0].weight = 1;
                    300:         peers->peer[0].effective_weight = 1;
                    301:         peers->peer[0].current_weight = 0;
                    302:         peers->peer[0].max_fails = 1;
                    303:         peers->peer[0].fail_timeout = 10;
                    304: 
                    305:     } else {
                    306: 
                    307:         for (i = 0; i < ur->naddrs; i++) {
                    308: 
                    309:             len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;
                    310: 
                    311:             p = ngx_pnalloc(r->pool, len);
                    312:             if (p == NULL) {
                    313:                 return NGX_ERROR;
                    314:             }
                    315: 
                    316:             len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN);
                    317:             len = ngx_sprintf(&p[len], ":%d", ur->port) - p;
                    318: 
                    319:             sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in));
                    320:             if (sin == NULL) {
                    321:                 return NGX_ERROR;
                    322:             }
                    323: 
                    324:             sin->sin_family = AF_INET;
                    325:             sin->sin_port = htons(ur->port);
                    326:             sin->sin_addr.s_addr = ur->addrs[i];
                    327: 
                    328:             peers->peer[i].sockaddr = (struct sockaddr *) sin;
                    329:             peers->peer[i].socklen = sizeof(struct sockaddr_in);
                    330:             peers->peer[i].name.len = len;
                    331:             peers->peer[i].name.data = p;
                    332:             peers->peer[i].weight = 1;
                    333:             peers->peer[i].effective_weight = 1;
                    334:             peers->peer[i].current_weight = 0;
                    335:             peers->peer[i].max_fails = 1;
                    336:             peers->peer[i].fail_timeout = 10;
                    337:         }
                    338:     }
                    339: 
                    340:     rrp->peers = peers;
                    341:     rrp->current = 0;
                    342: 
                    343:     if (rrp->peers->number <= 8 * sizeof(uintptr_t)) {
                    344:         rrp->tried = &rrp->data;
                    345:         rrp->data = 0;
                    346: 
                    347:     } else {
                    348:         n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
                    349:                 / (8 * sizeof(uintptr_t));
                    350: 
                    351:         rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t));
                    352:         if (rrp->tried == NULL) {
                    353:             return NGX_ERROR;
                    354:         }
                    355:     }
                    356: 
                    357:     r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer;
                    358:     r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
                    359:     r->upstream->peer.tries = rrp->peers->number;
                    360: #if (NGX_HTTP_SSL)
                    361:     r->upstream->peer.set_session = ngx_http_upstream_empty_set_session;
                    362:     r->upstream->peer.save_session = ngx_http_upstream_empty_save_session;
                    363: #endif
                    364: 
                    365:     return NGX_OK;
                    366: }
                    367: 
                    368: 
                    369: ngx_int_t
                    370: ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
                    371: {
                    372:     ngx_http_upstream_rr_peer_data_t  *rrp = data;
                    373: 
                    374:     ngx_int_t                      rc;
                    375:     ngx_uint_t                     i, n;
                    376:     ngx_http_upstream_rr_peer_t   *peer;
                    377:     ngx_http_upstream_rr_peers_t  *peers;
                    378: 
                    379:     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    380:                    "get rr peer, try: %ui", pc->tries);
                    381: 
                    382:     /* ngx_lock_mutex(rrp->peers->mutex); */
                    383: 
                    384:     pc->cached = 0;
                    385:     pc->connection = NULL;
                    386: 
                    387:     if (rrp->peers->single) {
                    388:         peer = &rrp->peers->peer[0];
                    389: 
                    390:         if (peer->down) {
                    391:             goto failed;
                    392:         }
                    393: 
                    394:     } else {
                    395: 
                    396:         /* there are several peers */
                    397: 
                    398:         peer = ngx_http_upstream_get_peer(rrp);
                    399: 
                    400:         if (peer == NULL) {
                    401:             goto failed;
                    402:         }
                    403: 
                    404:         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    405:                        "get rr peer, current: %ui %i",
                    406:                        rrp->current, peer->current_weight);
                    407:     }
                    408: 
                    409:     pc->sockaddr = peer->sockaddr;
                    410:     pc->socklen = peer->socklen;
                    411:     pc->name = &peer->name;
                    412: 
                    413:     /* ngx_unlock_mutex(rrp->peers->mutex); */
                    414: 
                    415:     if (pc->tries == 1 && rrp->peers->next) {
                    416:         pc->tries += rrp->peers->next->number;
                    417:     }
                    418: 
                    419:     return NGX_OK;
                    420: 
                    421: failed:
                    422: 
                    423:     peers = rrp->peers;
                    424: 
                    425:     if (peers->next) {
                    426: 
                    427:         /* ngx_unlock_mutex(peers->mutex); */
                    428: 
                    429:         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers");
                    430: 
                    431:         rrp->peers = peers->next;
                    432:         pc->tries = rrp->peers->number;
                    433: 
                    434:         n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
                    435:                 / (8 * sizeof(uintptr_t));
                    436: 
                    437:         for (i = 0; i < n; i++) {
                    438:              rrp->tried[i] = 0;
                    439:         }
                    440: 
                    441:         rc = ngx_http_upstream_get_round_robin_peer(pc, rrp);
                    442: 
                    443:         if (rc != NGX_BUSY) {
                    444:             return rc;
                    445:         }
                    446: 
                    447:         /* ngx_lock_mutex(peers->mutex); */
                    448:     }
                    449: 
                    450:     /* all peers failed, mark them as live for quick recovery */
                    451: 
                    452:     for (i = 0; i < peers->number; i++) {
                    453:         peers->peer[i].fails = 0;
                    454:     }
                    455: 
                    456:     /* ngx_unlock_mutex(peers->mutex); */
                    457: 
                    458:     pc->name = peers->name;
                    459: 
                    460:     return NGX_BUSY;
                    461: }
                    462: 
                    463: 
                    464: static ngx_http_upstream_rr_peer_t *
                    465: ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp)
                    466: {
                    467:     time_t                        now;
                    468:     uintptr_t                     m;
                    469:     ngx_int_t                     total;
                    470:     ngx_uint_t                    i, n;
                    471:     ngx_http_upstream_rr_peer_t  *peer, *best;
                    472: 
                    473:     now = ngx_time();
                    474: 
                    475:     best = NULL;
                    476:     total = 0;
                    477: 
                    478:     for (i = 0; i < rrp->peers->number; i++) {
                    479: 
                    480:         n = i / (8 * sizeof(uintptr_t));
                    481:         m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
                    482: 
                    483:         if (rrp->tried[n] & m) {
                    484:             continue;
                    485:         }
                    486: 
                    487:         peer = &rrp->peers->peer[i];
                    488: 
                    489:         if (peer->down) {
                    490:             continue;
                    491:         }
                    492: 
                    493:         if (peer->max_fails
                    494:             && peer->fails >= peer->max_fails
                    495:             && now - peer->checked <= peer->fail_timeout)
                    496:         {
                    497:             continue;
                    498:         }
                    499: 
                    500:         peer->current_weight += peer->effective_weight;
                    501:         total += peer->effective_weight;
                    502: 
                    503:         if (peer->effective_weight < peer->weight) {
                    504:             peer->effective_weight++;
                    505:         }
                    506: 
                    507:         if (best == NULL || peer->current_weight > best->current_weight) {
                    508:             best = peer;
                    509:         }
                    510:     }
                    511: 
                    512:     if (best == NULL) {
                    513:         return NULL;
                    514:     }
                    515: 
                    516:     i = best - &rrp->peers->peer[0];
                    517: 
                    518:     rrp->current = i;
                    519: 
                    520:     n = i / (8 * sizeof(uintptr_t));
                    521:     m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
                    522: 
                    523:     rrp->tried[n] |= m;
                    524: 
                    525:     best->current_weight -= total;
                    526: 
                    527:     if (now - best->checked > best->fail_timeout) {
                    528:         best->checked = now;
                    529:     }
                    530: 
                    531:     return best;
                    532: }
                    533: 
                    534: 
                    535: void
                    536: ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
                    537:     ngx_uint_t state)
                    538: {
                    539:     ngx_http_upstream_rr_peer_data_t  *rrp = data;
                    540: 
                    541:     time_t                       now;
                    542:     ngx_http_upstream_rr_peer_t  *peer;
                    543: 
                    544:     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    545:                    "free rr peer %ui %ui", pc->tries, state);
                    546: 
                    547:     /* TODO: NGX_PEER_KEEPALIVE */
                    548: 
                    549:     if (rrp->peers->single) {
                    550:         pc->tries = 0;
                    551:         return;
                    552:     }
                    553: 
                    554:     peer = &rrp->peers->peer[rrp->current];
                    555: 
                    556:     if (state & NGX_PEER_FAILED) {
                    557:         now = ngx_time();
                    558: 
                    559:         /* ngx_lock_mutex(rrp->peers->mutex); */
                    560: 
                    561:         peer->fails++;
                    562:         peer->accessed = now;
                    563:         peer->checked = now;
                    564: 
                    565:         if (peer->max_fails) {
                    566:             peer->effective_weight -= peer->weight / peer->max_fails;
                    567:         }
                    568: 
                    569:         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    570:                        "free rr peer failed: %ui %i",
                    571:                        rrp->current, peer->effective_weight);
                    572: 
                    573:         if (peer->effective_weight < 0) {
                    574:             peer->effective_weight = 0;
                    575:         }
                    576: 
                    577:         /* ngx_unlock_mutex(rrp->peers->mutex); */
                    578: 
                    579:     } else {
                    580: 
                    581:         /* mark peer live if check passed */
                    582: 
                    583:         if (peer->accessed < peer->checked) {
                    584:             peer->fails = 0;
                    585:         }
                    586:     }
                    587: 
                    588:     if (pc->tries) {
                    589:         pc->tries--;
                    590:     }
                    591: 
                    592:     /* ngx_unlock_mutex(rrp->peers->mutex); */
                    593: }
                    594: 
                    595: 
                    596: #if (NGX_HTTP_SSL)
                    597: 
                    598: ngx_int_t
                    599: ngx_http_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc,
                    600:     void *data)
                    601: {
                    602:     ngx_http_upstream_rr_peer_data_t  *rrp = data;
                    603: 
                    604:     ngx_int_t                     rc;
                    605:     ngx_ssl_session_t            *ssl_session;
                    606:     ngx_http_upstream_rr_peer_t  *peer;
                    607: 
                    608:     peer = &rrp->peers->peer[rrp->current];
                    609: 
                    610:     /* TODO: threads only mutex */
                    611:     /* ngx_lock_mutex(rrp->peers->mutex); */
                    612: 
                    613:     ssl_session = peer->ssl_session;
                    614: 
                    615:     rc = ngx_ssl_set_session(pc->connection, ssl_session);
                    616: 
                    617:     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    618:                    "set session: %p:%d",
                    619:                    ssl_session, ssl_session ? ssl_session->references : 0);
                    620: 
                    621:     /* ngx_unlock_mutex(rrp->peers->mutex); */
                    622: 
                    623:     return rc;
                    624: }
                    625: 
                    626: 
                    627: void
                    628: ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc,
                    629:     void *data)
                    630: {
                    631:     ngx_http_upstream_rr_peer_data_t  *rrp = data;
                    632: 
                    633:     ngx_ssl_session_t            *old_ssl_session, *ssl_session;
                    634:     ngx_http_upstream_rr_peer_t  *peer;
                    635: 
                    636:     ssl_session = ngx_ssl_get_session(pc->connection);
                    637: 
                    638:     if (ssl_session == NULL) {
                    639:         return;
                    640:     }
                    641: 
                    642:     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    643:                    "save session: %p:%d", ssl_session, ssl_session->references);
                    644: 
                    645:     peer = &rrp->peers->peer[rrp->current];
                    646: 
                    647:     /* TODO: threads only mutex */
                    648:     /* ngx_lock_mutex(rrp->peers->mutex); */
                    649: 
                    650:     old_ssl_session = peer->ssl_session;
                    651:     peer->ssl_session = ssl_session;
                    652: 
                    653:     /* ngx_unlock_mutex(rrp->peers->mutex); */
                    654: 
                    655:     if (old_ssl_session) {
                    656: 
                    657:         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    658:                        "old session: %p:%d",
                    659:                        old_ssl_session, old_ssl_session->references);
                    660: 
                    661:         /* TODO: may block */
                    662: 
                    663:         ngx_ssl_free_session(old_ssl_session);
                    664:     }
                    665: }
                    666: 
                    667: 
                    668: static ngx_int_t
                    669: ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc, void *data)
                    670: {
                    671:     return NGX_OK;
                    672: }
                    673: 
                    674: 
                    675: static void
                    676: ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc, void *data)
                    677: {
                    678:     return;
                    679: }
                    680: 
                    681: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>