1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef LISTEN_H
#define LISTEN_H
/**
* $Id$
*
* @file listen.h
* @brief The listener API.
*
* @copyright 2015 The FreeRADIUS server project
*/
/*
* Types of listeners.
*
* Ordered by priority!
*/
typedef enum RAD_LISTEN_TYPE {
RAD_LISTEN_NONE = 0,
RAD_LISTEN_PROXY,
RAD_LISTEN_AUTH,
RAD_LISTEN_ACCT,
RAD_LISTEN_DETAIL,
RAD_LISTEN_VQP,
RAD_LISTEN_DHCP,
RAD_LISTEN_COMMAND,
RAD_LISTEN_COA,
RAD_LISTEN_MAX
} RAD_LISTEN_TYPE;
typedef enum RAD_LISTEN_STATUS {
RAD_LISTEN_STATUS_INIT = 0,
RAD_LISTEN_STATUS_KNOWN,
RAD_LISTEN_STATUS_PAUSE,
RAD_LISTEN_STATUS_RESUME,
RAD_LISTEN_STATUS_FROZEN,
RAD_LISTEN_STATUS_EOL,
RAD_LISTEN_STATUS_REMOVE_NOW
} RAD_LISTEN_STATUS;
typedef struct rad_listen rad_listen_t;
typedef int (*rad_listen_recv_t)(rad_listen_t *);
typedef int (*rad_listen_send_t)(rad_listen_t *, REQUEST *);
typedef int (*rad_listen_print_t)(rad_listen_t const *, char *, size_t);
typedef int (*rad_listen_encode_t)(rad_listen_t *, REQUEST *);
typedef int (*rad_listen_decode_t)(rad_listen_t *, REQUEST *);
struct rad_listen {
rad_listen_t *next; /* should be rbtree stuff */
/*
* For normal sockets.
*/
RAD_LISTEN_TYPE type;
int fd;
char const *server;
int status;
int count;
#ifdef WITH_TCP
rbtree_t *children;
rad_listen_t *parent;
bool dual;
bool proxy_protocol; //!< haproxy protocol
#endif
bool nodup;
bool synchronous;
bool dead;
uint32_t workers;
#ifdef WITH_TLS
fr_tls_server_conf_t *tls;
bool check_client_connections;
bool nonblock;
bool blocked;
#ifdef WITH_RADIUSV11
fr_radiusv11_t radiusv11;
#endif
#ifdef WITH_COA_TUNNEL
char const *key; /* Originating-Realm-Key */
bool send_coa; /* to the NAS */
uint32_t coa_irt;
uint32_t coa_mrc;
uint32_t coa_mrt;
uint32_t coa_mrd;
int num_ids_used; /* for proxying CoA packets */
#endif
#endif
rad_listen_recv_t recv;
rad_listen_send_t send;
/*
* We don't need a proxy_recv, because the main loop in
* process.c calls listener->recv(), and we don't know
* what kind of packet we're receiving until we receive
* it.
*/
rad_listen_send_t proxy_send;
rad_listen_encode_t encode;
rad_listen_decode_t decode;
rad_listen_encode_t proxy_encode;
rad_listen_decode_t proxy_decode;
rad_listen_print_t print;
CONF_SECTION const *cs;
void *data;
#ifdef WITH_STATS
fr_stats_t stats;
#endif
};
/*
* This shouldn't really be exposed...
*/
typedef struct listen_socket_t {
/*
* For normal sockets.
*/
fr_ipaddr_t my_ipaddr;
uint16_t my_port;
char const *interface;
#ifdef SO_BROADCAST
int broadcast;
#endif
int recv_buff;
time_t rate_time;
uint32_t rate_pps_old;
uint32_t rate_pps_now;
uint32_t max_rate;
/* for outgoing sockets */
home_server_t *home;
fr_ipaddr_t other_ipaddr;
uint16_t other_port;
int proto;
#ifdef WITH_TCP
/* for a proxy connecting to home servers */
time_t last_packet;
time_t opened;
fr_event_t *ev;
fr_socket_limit_t limit;
struct listen_socket_t *parent;
RADCLIENT *client;
RADIUS_PACKET *packet; /* for reading partial packets */
fr_ipaddr_t haproxy_src_ipaddr; //!< for proxy_protocol
fr_ipaddr_t haproxy_dst_ipaddr;
uint16_t haproxy_src_port;
uint16_t haproxy_dst_port;
#endif
#ifdef WITH_TLS
tls_session_t *ssn;
REQUEST *request; /* horrible hacks */
VALUE_PAIR *certs;
uint32_t connect_timeout;
pthread_mutex_t mutex;
uint8_t *data;
size_t partial;
enum {
LISTEN_TLS_INIT = 0,
LISTEN_TLS_CHECKING,
LISTEN_TLS_SETUP,
LISTEN_TLS_RUNNING,
} state;
#ifdef WITH_RADIUSV11
bool alpn_checked;
bool radiusv11; //!< defaults to "no"!
#endif
#endif
RADCLIENT_LIST *clients;
} listen_socket_t;
#endif /* LISTEN_H */
|