1 /*
2  * twemproxy - A fast and lightweight proxy for memcached protocol.
3  * Copyright (C) 2011 Twitter, Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef _NC_SERVER_H_
19 #define _NC_SERVER_H_
20 
21 #include <nc_core.h>
22 
23 /*
24  * server_pool is a collection of servers and their continuum. Each
25  * server_pool is the owner of a single proxy connection and one or
26  * more client connections. server_pool itself is owned by the current
27  * context.
28  *
29  * Each server is the owner of one or more server connections. server
30  * itself is owned by the server_pool.
31  *
32  *  +-------------+
33  *  |             |<---------------------+
34  *  |             |<------------+        |
35  *  |             |     +-------+--+-----+----+--------------+
36  *  |   pool 0    |+--->|          |          |              |
37  *  |             |     | server 0 | server 1 | ...     ...  |
38  *  |             |     |          |          |              |--+
39  *  |             |     +----------+----------+--------------+  |
40  *  +-------------+                                             //
41  *  |             |
42  *  |             |
43  *  |             |
44  *  |   pool 1    |
45  *  |             |
46  *  |             |
47  *  |             |
48  *  +-------------+
49  *  |             |
50  *  |             |
51  *  .             .
52  *  .    ...      .
53  *  .             .
54  *  |             |
55  *  |             |
56  *  +-------------+
57  *            |
58  *            |
59  *            //
60  */
61 
62 typedef uint32_t (*hash_t)(const char *, size_t);
63 
64 struct continuum {
65     uint32_t index;  /* server index */
66     uint32_t value;  /* hash value */
67 };
68 
69 struct server {
70     uint32_t           idx;           /* server index */
71     struct server_pool *owner;        /* owner pool */
72 
73     struct string      pname;         /* hostname:port:weight (ref in conf_server) */
74     struct string      name;          /* hostname:port or [name] (ref in conf_server) */
75     struct string      addrstr;       /* hostname (ref in conf_server) */
76     uint16_t           port;          /* port */
77     uint32_t           weight;        /* weight */
78     struct sockinfo    info;          /* server socket info */
79 
80     uint32_t           ns_conn_q;     /* # server connection */
81     struct conn_tqh    s_conn_q;      /* server connection q */
82 
83     int64_t            next_retry;    /* next retry time in usec */
84     uint32_t           failure_count; /* # consecutive failures */
85 };
86 
87 struct server_pool {
88     uint32_t           idx;                  /* pool index */
89     struct context     *ctx;                 /* owner context */
90 
91     struct conn        *p_conn;              /* proxy connection (listener) */
92     uint32_t           nc_conn_q;            /* # client connection */
93     struct conn_tqh    c_conn_q;             /* client connection q */
94 
95     struct array       server;               /* server[] */
96     uint32_t           ncontinuum;           /* # continuum points */
97     uint32_t           nserver_continuum;    /* # servers - live and dead on continuum (const) */
98     struct continuum   *continuum;           /* continuum */
99     uint32_t           nlive_server;         /* # live server */
100     int64_t            next_rebuild;         /* next distribution rebuild time in usec */
101 
102     struct string      name;                 /* pool name (ref in conf_pool) */
103     struct string      addrstr;              /* pool address - hostname:port (ref in conf_pool) */
104     uint16_t           port;                 /* port */
105     struct sockinfo    info;                 /* listen socket info */
106     mode_t             perm;                 /* socket permission */
107     int                dist_type;            /* distribution type (dist_type_t) */
108     int                key_hash_type;        /* key hash type (hash_type_t) */
109     hash_t             key_hash;             /* key hasher */
110     struct string      hash_tag;             /* key hash tag (ref in conf_pool) */
111     int                timeout;              /* timeout in msec */
112     int                backlog;              /* listen backlog */
113     int                redis_db;             /* redis database to connect to */
114     uint32_t           client_connections;   /* maximum # client connection */
115     uint32_t           server_connections;   /* maximum # server connection */
116     int64_t            server_retry_timeout; /* server retry timeout in usec */
117     uint32_t           server_failure_limit; /* server failure limit */
118     struct string      redis_auth;           /* redis_auth password (matches requirepass on redis) */
119     unsigned           require_auth;         /* require_auth? */
120     unsigned           auto_eject_hosts:1;   /* auto_eject_hosts? */
121     unsigned           preconnect:1;         /* preconnect? */
122     unsigned           redis:1;              /* redis? */
123     unsigned           tcpkeepalive:1;       /* tcpkeepalive? */
124 };
125 
126 void server_ref(struct conn *conn, void *owner);
127 void server_unref(struct conn *conn);
128 int server_timeout(struct conn *conn);
129 bool server_active(const struct conn *conn);
130 rstatus_t server_init(struct array *server, struct array *conf_server, struct server_pool *sp);
131 void server_deinit(struct array *server);
132 struct conn *server_conn(struct server *server);
133 rstatus_t server_connect(struct context *ctx, struct server *server, struct conn *conn);
134 void server_close(struct context *ctx, struct conn *conn);
135 void server_connected(struct context *ctx, struct conn *conn);
136 void server_ok(struct context *ctx, struct conn *conn);
137 
138 uint32_t server_pool_idx(const struct server_pool *pool, const uint8_t *key, uint32_t keylen);
139 struct conn *server_pool_conn(struct context *ctx, struct server_pool *pool, const uint8_t *key, uint32_t keylen);
140 rstatus_t server_pool_run(struct server_pool *pool);
141 rstatus_t server_pool_preconnect(struct context *ctx);
142 void server_pool_disconnect(struct context *ctx);
143 rstatus_t server_pool_init(struct array *server_pool, struct array *conf_pool, struct context *ctx);
144 void server_pool_deinit(struct array *server_pool);
145 
146 #endif
147