static ngx_int_t ngx_http_upstream_init_zeromq_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_http_upstream_zeromq_peer_data_t *zp; zp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_zeromq_peer_data_t)); if (zp == NULL) { return NGX_ERROR; } zp ->request = r; zp ->zmq = NULL; ngx_http_set_ctx(r, NULL, ngx_zeromq_module); r->upstream->peer.data = &zp->rrp; if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.get = ngx_http_upstream_get_zeromq_peer; r->upstream->peer.free = ngx_http_upstream_free_zeromq_peer; return NGX_OK; }
static ngx_int_t ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_http_upstream_lc_peer_data_t *lcp; ngx_http_upstream_least_conn_conf_t *lcf; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "init least conn peer"); lcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_least_conn_module); lcp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_lc_peer_data_t)); if (lcp == NULL) { return NGX_ERROR; } lcp->conns = lcf->conns; r->upstream->peer.data = &lcp->rrp; if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.get = ngx_http_upstream_get_least_conn_peer; r->upstream->peer.free = ngx_http_upstream_free_least_conn_peer; lcp->get_rr_peer = ngx_http_upstream_get_round_robin_peer; lcp->free_rr_peer = ngx_http_upstream_free_round_robin_peer; return NGX_OK; }
static ngx_int_t ngx_http_lua_balancer_init_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_http_lua_srv_conf_t *bcf; ngx_http_lua_balancer_peer_data_t *bp; bp = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_balancer_peer_data_t)); if (bp == NULL) { return NGX_ERROR; } r->upstream->peer.data = &bp->rrp; if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.get = ngx_http_lua_balancer_get_peer; r->upstream->peer.free = ngx_http_lua_balancer_free_peer; #if (NGX_HTTP_SSL) r->upstream->peer.set_session = ngx_http_lua_balancer_set_session; r->upstream->peer.save_session = ngx_http_lua_balancer_save_session; #endif bcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_lua_module); bp->conf = bcf; bp->request = r; return NGX_OK; }
static ngx_int_t ngx_http_upstream_session_sticky_init_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_int_t rc; ngx_http_ss_ctx_t *ctx; ngx_http_upstream_ss_srv_conf_t *sscf; ngx_http_upstream_ss_peer_data_t *sspd; sspd = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_ss_peer_data_t)); if (sspd == NULL) { return NGX_ERROR; } r->upstream->peer.data = &sspd->rrp; rc = ngx_http_upstream_init_round_robin_peer(r, us); if (rc != NGX_OK) { return rc; } sscf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_session_sticky_module); ctx = ngx_http_get_module_ctx(r, ngx_http_upstream_session_sticky_module); if (ctx == NULL) { ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ss_ctx_t)); if (ctx == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "session sticky ctx allocated failed"); return NGX_ERROR; } ctx->sscf = sscf; ngx_http_set_ctx(r, ctx, ngx_http_upstream_session_sticky_module); rc = ngx_http_session_sticky_get_cookie(r); if (rc != NGX_OK) { return rc; } } else { if (ctx->sscf != sscf) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "different sscf with header_handler"); } } sspd->r = r; sspd->sscf = sscf; sspd->get_rr_peer = ngx_http_upstream_get_round_robin_peer; r->upstream->peer.data = sspd; r->upstream->peer.get = ngx_http_upstream_session_sticky_get_peer; return NGX_OK; }
static ngx_int_t ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { struct sockaddr_in *sin; #if (NGX_HAVE_INET6) struct sockaddr_in6 *sin6; #endif ngx_http_upstream_ip_hash_peer_data_t *iphp; iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t)); if (iphp == NULL) { return NGX_ERROR; } r->upstream->peer.data = &iphp->rrp; if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer; switch (r->connection->sockaddr->sa_family) { case AF_INET: sin = (struct sockaddr_in *) r->connection->sockaddr; iphp->addr = (u_char *) &sin->sin_addr.s_addr; iphp->addrlen = 3; break; #if (NGX_HAVE_INET6) case AF_INET6: sin6 = (struct sockaddr_in6 *) r->connection->sockaddr; iphp->addr = (u_char *) &sin6->sin6_addr.s6_addr; iphp->addrlen = 16; break; #endif default: iphp->addr = ngx_http_upstream_ip_hash_pseudo_addr; iphp->addrlen = 3; } iphp->hash = 89; iphp->tries = 0; iphp->get_rr_peer = ngx_http_upstream_get_round_robin_peer; return NGX_OK; }
static ngx_int_t ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "init least conn peer"); if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.get = ngx_http_upstream_get_least_conn_peer; return NGX_OK; }
static ngx_int_t ngx_http_upstream_init_q_chash_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_int_t rc; ngx_http_upstream_q_chash_srv_conf_t *uchscf; ngx_http_upstream_q_chash_peer_data_t *qchp; ngx_http_upstream_q_chash_ring *q_chash_ring; ngx_str_t evaluated_key_to_hash; uchscf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_q_chash_module); if (uchscf == NULL) { return NGX_ERROR; } q_chash_ring = uchscf->q_chash_ring; qchp = ngx_pcalloc(r->pool, sizeof(*qchp)); if(qchp == NULL) return NGX_ERROR; r->upstream->peer.data = &qchp->rrp; qchp->q_chash_ring = q_chash_ring; qchp->get_rr_peer = ngx_http_upstream_get_round_robin_peer; qchp->tries = 0; qchp->ignore = 0; qchp->rr_mode = 0; rc = ngx_http_upstream_init_round_robin_peer(r, us); if(rc != NGX_OK) return NGX_ERROR; r->upstream->peer.get = ngx_http_upstream_get_q_chash_peer; // calculate the vnode_index if(q_chash_ring->nr_valid_peers > 1) { if (ngx_http_script_run(r, &evaluated_key_to_hash, uchscf->lengths->elts, 0, uchscf->values->elts) == NULL) return NGX_ERROR; qchp->point = (uint32_t)ngx_crc32_long(evaluated_key_to_hash.data, evaluated_key_to_hash.len); qchp->vnode_index = q_chash_find(q_chash_ring, qchp->point); ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "q_chash key %V, point %uD, vnode_index %ui", &evaluated_key_to_hash, qchp->point, qchp->vnode_index); } return NGX_OK; }
static ngx_int_t ngx_http_upstream_init_consistent_hash_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_str_t evaluated_key_to_hash; ngx_http_upstream_consistent_hash_srv_conf_t *uchscf; ngx_http_upstream_consistent_hash_peer_data_t *uchpd; uchscf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_consistent_hash_module); if (uchscf == NULL) { return NGX_ERROR; } uchpd = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_consistent_hash_peer_data_t)); if (uchpd == NULL) { return NGX_ERROR; } r->upstream->peer.data = &uchpd->rrp; if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.get = ngx_http_upstream_get_consistent_hash_peer; uchpd->buckets = uchscf->data; uchpd->tries = 0; if (ngx_http_script_run(r, &evaluated_key_to_hash, uchscf->lengths->elts, 0, uchscf->values->elts) == NULL) { return NGX_ERROR; } uchpd->point = ngx_crc32_long(evaluated_key_to_hash.data, evaluated_key_to_hash.len); uchpd->get_rr_peer = ngx_http_upstream_get_round_robin_peer; return NGX_OK; }
static ngx_int_t ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { u_char *p; struct sockaddr_in *sin; ngx_http_upstream_ip_hash_peer_data_t *iphp; iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t)); if (iphp == NULL) { return NGX_ERROR; } r->upstream->peer.data = &iphp->rrp; if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer; /* AF_INET only */ if (r->connection->sockaddr->sa_family == AF_INET) { sin = (struct sockaddr_in *) r->connection->sockaddr; p = (u_char *) &sin->sin_addr.s_addr; iphp->addr[0] = p[0]; iphp->addr[1] = p[1]; iphp->addr[2] = p[2]; } else { iphp->addr[0] = 0; iphp->addr[1] = 0; iphp->addr[2] = 0; } iphp->hash = 89; iphp->tries = 0; iphp->get_rr_peer = ngx_http_upstream_get_round_robin_peer; return NGX_OK; }
static ngx_int_t ngx_http_upstream_init_cookie_hash_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_table_elt_t** cookies; ngx_http_upstream_cookie_hash_peer_data_t *ckhp; ngx_uint_t i; ckhp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_cookie_hash_peer_data_t)); if (ckhp == NULL) { return NGX_ERROR; } ngx_memset(ckhp->sess_id, 0, sizeof(ckhp->sess_id)); r->upstream->peer.data = &ckhp->rrp; if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.get = ngx_http_upstream_get_cookie_hash_peer; cookies = r->headers_in.cookies.elts; for(i=0; i<r->headers_in.cookies.nelts; i++) { if (0 == ngx_strcmp((u_char*)"Cookie", cookies[i]->key.data)) { if(0 == get_session_id(r, (char*)cookies[i]->value.data, "PHPSESSID", (char*)ckhp->sess_id)) { if (strlen((char*)ckhp->sess_id)>0) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "session id: %s", ckhp->sess_id); break; } } } } ckhp->hash = 89; ckhp->tries = 0; ckhp->get_rr_peer = ngx_http_upstream_get_round_robin_peer; return NGX_OK; }
ngx_int_t ngx_http_upstream_init_idempotent_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_http_upstream_idempotent_peer_data_t *iphp; iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_idempotent_peer_data_t)); if (iphp == NULL) { return NGX_ERROR; } iphp->method = r->method; r->upstream->peer.data = &iphp->rrp; if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.free = ngx_http_upstream_free_idempotent_peer; return NGX_OK; }
static ngx_int_t __init_peer(ngx_http_request_t * r, ngx_http_upstream_srv_conf_t * us) { if (!r || !r->parent) { return NGX_ERROR; } ngx_http_peer_selector_peer_data_t *peer_data = ngx_palloc(r->pool, sizeof(ngx_http_peer_selector_peer_data_t)); if (!peer_data) { return NGX_ERROR; } peer_data->peer = ngx_http_get_addon_module_ctx(r); r->upstream->peer.data = &peer_data->rrp; if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.get = __get_peer; return NGX_OK; }
/* * function called by the upstream module when it inits each peer * it's called once per request */ static ngx_int_t ngx_http_init_sticky_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_http_sticky_peer_data_t *iphp; ngx_str_t route; ngx_uint_t i; ngx_int_t n; /* alloc custom sticky struct */ iphp = ngx_palloc(r->pool, sizeof(ngx_http_sticky_peer_data_t)); if (iphp == NULL) { return NGX_ERROR; } /* attach it to the request upstream data */ r->upstream->peer.data = &iphp->rrp; /* call the rr module on which the sticky is based on */ if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } /* set the callback to select the next peer to use */ r->upstream->peer.get = ngx_http_get_sticky_peer; /* init the custom sticky struct */ iphp->get_rr_peer = ngx_http_upstream_get_round_robin_peer; iphp->selected_peer = -1; iphp->no_fallback = 0; iphp->sticky_conf = ngx_http_conf_upstream_srv_conf(us, ngx_http_sticky_module); iphp->request = r; /* check weather a cookie is present or not and save it */ if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &iphp->sticky_conf->cookie_name, &route) != NGX_DECLINED) { /* a route cookie has been found. Let's give it a try */ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "[sticky/init_sticky_peer] got cookie route=%V, " "let's try to find a matching peer", &route); /* hash or hmac, just compare digest */ if (iphp->sticky_conf->hash || iphp->sticky_conf->hmac) { /* search the digest found in the cookie in the peer digest list */ for (i = 0; i < iphp->rrp.peers->number; i++) { /* ensure the both len are equal and > 0 */ if (iphp->sticky_conf->peers[i].digest.len != route.len || route.len <= 0) { continue; } if (!ngx_strncmp(iphp->sticky_conf->peers[i].digest.data, route.data, route.len)) { /* we found a match */ iphp->selected_peer = i; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "[sticky/init_sticky_peer] the route " "\"%V\"matches peer at index %ui", &route, i); return NGX_OK; } } } else { /* * switch back to index, just convert to integer and ensure it * corresponds to a valid peer */ n = ngx_atoi(route.data, route.len); if (n == NGX_ERROR) { ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, "[sticky/init_sticky_peer] unable to convert " "the route \"%V\" to an integer value", &route); } else if (n >= 0 && n < (ngx_int_t) iphp->rrp.peers->number) { /* found one */ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "[sticky/init_sticky_peer] the route \"%V\" " "matches peer at index %i", &route, n); iphp->selected_peer = n; return NGX_OK; } } /* nothing was found, just continue with rr */ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "[sticky/init_sticky_peer] the route \"%V\"" "does not match any peer. Just ignoring it ...", &route); return NGX_OK; } /* nothing found */ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "[sticky/init_sticky_peer] route cookie not found"); return NGX_OK; /* return OK, in order to continue */ }