summaryrefslogtreecommitdiffstats
path: root/src/include/listen.h
blob: a82b91d2962eaec079faf7ed7a5d31086e381400 (plain)
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 */