1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) Nginx, Inc.
5  */
6 
7 
8 #ifndef _NGX_STREAM_UPSTREAM_ROUND_ROBIN_H_INCLUDED_
9 #define _NGX_STREAM_UPSTREAM_ROUND_ROBIN_H_INCLUDED_
10 
11 
12 #include <ngx_config.h>
13 #include <ngx_core.h>
14 #include <ngx_stream.h>
15 
16 
17 typedef struct ngx_stream_upstream_rr_peer_s   ngx_stream_upstream_rr_peer_t;
18 
19 struct ngx_stream_upstream_rr_peer_s {
20     struct sockaddr                 *sockaddr;
21     socklen_t                        socklen;
22     ngx_str_t                        name;
23     ngx_str_t                        server;
24 
25     ngx_int_t                        current_weight;
26     ngx_int_t                        effective_weight;
27     ngx_int_t                        weight;
28 
29     ngx_uint_t                       conns;
30     ngx_uint_t                       max_conns;
31 
32     ngx_uint_t                       fails;
33     time_t                           accessed;
34     time_t                           checked;
35 
36     ngx_uint_t                       max_fails;
37     time_t                           fail_timeout;
38     ngx_msec_t                       slow_start;
39     ngx_msec_t                       start_time;
40 
41     ngx_uint_t                       down;
42 
43     void                            *ssl_session;
44     int                              ssl_session_len;
45 
46 #if (NGX_STREAM_UPSTREAM_ZONE)
47     ngx_atomic_t                     lock;
48 #endif
49 
50     ngx_stream_upstream_rr_peer_t   *next;
51 
52     NGX_COMPAT_BEGIN(25)
53     NGX_COMPAT_END
54 };
55 
56 
57 typedef struct ngx_stream_upstream_rr_peers_s  ngx_stream_upstream_rr_peers_t;
58 
59 struct ngx_stream_upstream_rr_peers_s {
60     ngx_uint_t                       number;
61 
62 #if (NGX_STREAM_UPSTREAM_ZONE)
63     ngx_slab_pool_t                 *shpool;
64     ngx_atomic_t                     rwlock;
65     ngx_stream_upstream_rr_peers_t  *zone_next;
66 #endif
67 
68     ngx_uint_t                       total_weight;
69 
70     unsigned                         single:1;
71     unsigned                         weighted:1;
72 
73     ngx_str_t                       *name;
74 
75     ngx_stream_upstream_rr_peers_t  *next;
76 
77     ngx_stream_upstream_rr_peer_t   *peer;
78 };
79 
80 
81 #if (NGX_STREAM_UPSTREAM_ZONE)
82 
83 #define ngx_stream_upstream_rr_peers_rlock(peers)                             \
84                                                                               \
85     if (peers->shpool) {                                                      \
86         ngx_rwlock_rlock(&peers->rwlock);                                     \
87     }
88 
89 #define ngx_stream_upstream_rr_peers_wlock(peers)                             \
90                                                                               \
91     if (peers->shpool) {                                                      \
92         ngx_rwlock_wlock(&peers->rwlock);                                     \
93     }
94 
95 #define ngx_stream_upstream_rr_peers_unlock(peers)                            \
96                                                                               \
97     if (peers->shpool) {                                                      \
98         ngx_rwlock_unlock(&peers->rwlock);                                    \
99     }
100 
101 
102 #define ngx_stream_upstream_rr_peer_lock(peers, peer)                         \
103                                                                               \
104     if (peers->shpool) {                                                      \
105         ngx_rwlock_wlock(&peer->lock);                                        \
106     }
107 
108 #define ngx_stream_upstream_rr_peer_unlock(peers, peer)                       \
109                                                                               \
110     if (peers->shpool) {                                                      \
111         ngx_rwlock_unlock(&peer->lock);                                       \
112     }
113 
114 #else
115 
116 #define ngx_stream_upstream_rr_peers_rlock(peers)
117 #define ngx_stream_upstream_rr_peers_wlock(peers)
118 #define ngx_stream_upstream_rr_peers_unlock(peers)
119 #define ngx_stream_upstream_rr_peer_lock(peers, peer)
120 #define ngx_stream_upstream_rr_peer_unlock(peers, peer)
121 
122 #endif
123 
124 
125 typedef struct {
126     ngx_uint_t                       config;
127     ngx_stream_upstream_rr_peers_t  *peers;
128     ngx_stream_upstream_rr_peer_t   *current;
129     uintptr_t                       *tried;
130     uintptr_t                        data;
131 } ngx_stream_upstream_rr_peer_data_t;
132 
133 
134 ngx_int_t ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
135     ngx_stream_upstream_srv_conf_t *us);
136 ngx_int_t ngx_stream_upstream_init_round_robin_peer(ngx_stream_session_t *s,
137     ngx_stream_upstream_srv_conf_t *us);
138 ngx_int_t ngx_stream_upstream_create_round_robin_peer(ngx_stream_session_t *s,
139     ngx_stream_upstream_resolved_t *ur);
140 ngx_int_t ngx_stream_upstream_get_round_robin_peer(ngx_peer_connection_t *pc,
141     void *data);
142 void ngx_stream_upstream_free_round_robin_peer(ngx_peer_connection_t *pc,
143     void *data, ngx_uint_t state);
144 
145 
146 #endif /* _NGX_STREAM_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ */
147