football
socket abstraction layer
Loading...
Searching...
No Matches
fb_service.h
Go to the documentation of this file.
1
8
9
10#pragma once
11
12#include <config.h>
13
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <unistd.h>
18#include <time.h>
19#include <stdbool.h>
20#include <sys/types.h>
21#include <sys/socket.h>
22#include <netinet/in.h>
23
24#ifdef FOOTBALL_THREADS
25#include <pthread.h>
26#endif
27
28#include "fb_public.h"
29#include "fb_transport.h"
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35/* Logging facilities */
36typedef enum fb_log_types_t {
37 FB_LOG_ERROR = 0, /* Nonmaskable */
38 FB_LOG_WARNING = 0x01,
39 FB_LOG_PARSER = 0x04,
40 FB_LOG_IO_TRACE = 0x08,
41 FB_LOG_CONN_STATUS = 0x10,
42 FB_LOG_CONN_ERROR = 0x20,
43 FB_LOG_TLS_STATUS = 0x100,
44 FB_LOG_TLS_ERROR = 0x200,
45 FB_LOG_HTTP_STATUS = 0x1000,
46 FB_LOG_HTTP_ERROR = 0x2000,
47 FB_LOG_HTTP_TRAFFIC = 0x4000,
48} FB_LOG_TYPE;
49
52#ifdef NDEBUG
53#define FB_WHERE(level) (level)
54#else
55#define FB_WHERE(level) __FILE__, __LINE__, __func__, (level)
56#endif
58#define fb_perror(errfunc) fb_log(FB_WHERE (FB_LOG_ERROR), (errfunc ": %s"), strerror (errno))
59
60
61/* Mutexes are allocated in the following orders:
62 - Service module -> socket manager
63 - Service -> connection
64*/
65/* Wrap pthread mutexes in a macro so we don't need to #ifdef every use. */
66#ifdef FOOTBALL_THREADS
67#ifdef NDEBUG
68#define fb_mutex_init(var) (pthread_mutex_init(var, NULL))
69#define fb_mutex_destroy(var) (pthread_mutex_destroy(var))
70#define fb_mutex_lock(var) (pthread_mutex_lock(var))
71#define fb_mutex_unlock(var) (pthread_mutex_unlock(var))
72#else
73#define fb_mutex_init(var) (assert(pthread_mutex_init(var, NULL) == 0))
74#define fb_mutex_destroy(var) (assert(pthread_mutex_destroy(var) == 0))
75#define fb_mutex_lock(var) (assert(pthread_mutex_lock(var) == 0))
76#define fb_mutex_unlock(var) (assert(pthread_mutex_unlock(var) == 0))
77#endif
78#else
79#define fb_mutex_init(mutex) ((void)0)
80#define fb_mutex_destroy(mutex) ((void)0)
81#define fb_mutex_lock(mutex) ((void)0)
82#define fb_mutex_unlock(mutex) ((void)0)
83#endif
84
86typedef enum fb_socket_type_t {
88 FB_SOCKTYPE_CONNECTION = 0x5285,
89 FB_SOCKTYPE_USER = 0xa9f7,
90 FB_SOCKTYPE_EVENT = 0xbd53
92
102
103typedef enum fb_socketid_t {
104 FB_SOCKET_LINE_IP4,
105 FB_SOCKET_LINE_IP6,
106 FB_SOCKET_HTTP_IP4,
107 FB_SOCKET_HTTP_IP6,
108 FB_SOCKET_HTTPS_IP4,
109 FB_SOCKET_HTTPS_IP6,
110 FB_SOCKET_COUNT
111} FB_SOCKETID;
112
114typedef union fb_socketaddr_t {
115 struct sockaddr_in ip4;
116#ifdef HAVE_IPV6
117 struct sockaddr_in6 ip6;
118#endif
120
121#define fb_http_socket(id) ((id) == FB_SOCKET_HTTP_IP4 || (id) == FB_SOCKET_HTTP_IP6 || \
122 (id) == FB_SOCKET_HTTPS_IP4 || (id) == FB_SOCKET_HTTPS_IP6)
123#define fb_ip6_socket(id) ((id) == FB_SOCKET_LINE_IP6 || (id) == FB_SOCKET_HTTP_IP6 || \
124 (id) == FB_SOCKET_HTTPS_IP6)
125#define fb_encrypted_socket(id) ((id) == FB_SOCKET_HTTPS_IP4 || (id) == FB_SOCKET_HTTPS_IP6)
126
132 int socket [FB_SOCKET_COUNT];
133 FB_SOCKETADDR address [FB_SOCKET_COUNT];
140#ifdef FOOTBALL_THREADS
141 pthread_mutex_t mutex;
142#endif
144};
145
146/* Nomenclature:
147 Message - Contains the message data and a use count, allowing
148 use in several Qs for efficiency.
149 Q a/k/a MessageList - Per-connection linked list of Messages.
150 Queue - header data structure for Q MessageList.
151 */
153typedef struct fb_message_t {
155 ssize_t length;
156 char *message;
158
160typedef struct fb_messagelist_t {
161 struct fb_messagelist_t *next;
162 FB_MESSAGE *message;
164
166typedef struct fb_ioqueue_t {
167 FB_MESSAGELIST *first;
168 FB_MESSAGELIST *last;
169 ssize_t consumed; /***< Number of bytes consumed in first message. */
171
173typedef struct fb_inputbuffer_t {
174 size_t size;
175 size_t capacity;
176 char *message;
178
180typedef struct fb_http_request_t {
182 bool headonly;
183 char *http;
184 char *host;
186 char *filename;
187 char *query_string;
189 char *websocket_key;
190 char *websocket_protocol;
191 char *websocket_version;
193 char *language;
194 bool invalid;
195 bool failure;
197
202 int socket;
203 FB_SOCKETSTATE state;
204 time_t expiry_time;
205 bool greeted;
206 bool http;
208 const FB_TRANSPORT_FUNCS *transport;
209#ifdef FB_HAVE_TLS
210 FB_TLS_CONTEXT tls;
211#endif
212 FB_HTTPREQUEST request;
216 time_t next_ping;
217 int domain;
218 union {
219 struct sockaddr_in ip4addr;
220#ifdef HAVE_IPV6
221 struct sockaddr_in6 ip6addr;
222#endif
223 } origin;
224 char *filename;
225#ifdef FOOTBALL_THREADS
226 pthread_mutex_t mutex;
227#endif
228 void *context;
230};
231
234 FB_SERVICE *service;
235 ssize_t iteration;
236};
237
238/* Message data management */
239extern void fb_free_freelists (void);
240extern FB_MESSAGE *fb_messagealloc(void);
241extern void fb_messagefree(FB_MESSAGE *freethis);
242
243extern FB_MESSAGELIST *fb_qalloc();
244extern void fb_qfree (FB_MESSAGELIST *freethis);
245
246extern bool fb_queue_add (FB_IOQUEUE *queue, FB_MESSAGE *message);
247extern bool fb_queue_empty (FB_IOQUEUE *q);
248extern void fb_queue_consume (FB_IOQUEUE *q, size_t consume);
249extern void fb_queue_destroy (FB_IOQUEUE *q);
250
251/* Destroy the service when all connections are closed. */
252extern void fb_destroy_service (struct fb_service_t *service);
253extern void fb_schedule_reap (FB_SERVICE *service);
254
255/* Transfer service for HELO <svc> or http://my.server/<service> */
256extern bool fb_transfer_by_name (FB_CONNECTION *connection, const char *name);
257
258/* Register/Unregister a connection with the socket manager */
259extern void fb_queue_event (FB_EVENT *event);
260extern void fb_dispose_event (FB_EVENT *event);
261extern bool fb_register (int socket, FB_SOCKETTYPE type, void *thing);
262extern void fb_unregister (int socket);
263
264/* Accept/Close & release a socket and its resources */
265extern FB_CONNECTION *fb_accept_connection (FB_SERVICE *service, FB_SOCKETID id);
266extern void fb_destroy_connection (FB_CONNECTION *connection);
267
268/* Event handling functions */
269extern bool fb_set_input_buffer_size (FB_CONNECTION *connection, size_t size);
270extern bool fb_recv_input (FB_CONNECTION *connection, ssize_t byte_count);
271extern FB_EVENT *fb_read_input (FB_EVENT *event, FB_CONNECTION *connection);
272extern FB_EVENT *fb_new_connect (FB_EVENT *event, FB_SERVICE *service);
273extern FB_EVENT *fb_send_output (FB_EVENT *event, FB_CONNECTION *connection);
274
275/* HTTP & Websocket support */
276extern FB_EVENT *fb_read_websocket_input (FB_EVENT *event, FB_CONNECTION *connection);
277extern bool fb_websocket_ping (FB_CONNECTION *connection);
278extern bool fb_websocket_announce_close (FB_CONNECTION *connection);
279extern bool fb_websocket_encode (FB_CONNECTION *connection);
280extern void fb_destroy_httprequest (FB_HTTPREQUEST *request);
281extern void fb_collect_http_request (FB_EVENT *event, FB_HTTPREQUEST *request);
282extern void fb_collect_http_parameter (char *line, FB_HTTPREQUEST *request);
283extern bool fb_http_command (const char *command);
284extern FB_EVENT *fb_execute_http_request (FB_EVENT *event, FB_CONNECTION *connection);
285
286/* Utility/TLS functions */
287extern int fb_create_argv (const char *commandline, char ***result);
288extern int fb_create_argv_from_query_string (const char *query_string, char ***result, char ***remainders);
289extern void fb_destroy_argv (char **argv);
290extern const char *fb_connection_info (FB_CONNECTION *connection);
291
292/* Enabling/disabling events for the socket manager */
293extern void fb_set_buffering (int socket_fd, bool enable);
294extern void fb_set_readable (int socket, bool enable);
295extern void fb_set_writable (int socket, bool enable);
296
297#define FAR_FUTURE ((time_t) (((time_t) 0x7fffffff) << ((sizeof (time_t) - 4) * 8)))
298
299#ifdef __cplusplus
300}
301#endif
302
Football public declarations.
enum fb_socket_state_t FB_SOCKETSTATE
Connection states.
bool fb_register(int socket, FB_SOCKETTYPE type, void *thing)
Add a socket to the registry.
Definition fb_socketmgr.c:195
void fb_unregister(int socket)
Remove a socket from the registry.
Definition fb_socketmgr.c:228
struct fb_inputbuffer_t FB_INPUTBUFFER
Connection input structure.
union fb_socketaddr_t FB_SOCKETADDR
Address of opposing end of a connection.
struct fb_ioqueue_t FB_IOQUEUE
Queue structure.
struct fb_message_t FB_MESSAGE
Message structure.
enum fb_socket_type_t FB_SOCKETTYPE
Magic numbers used to differentiate parameter types sent to fb_fprintf.
struct fb_http_request_t FB_HTTPREQUEST
Structure which collects HTTP request information as it is read.
struct fb_messagelist_t FB_MESSAGELIST
Q list structure.
fb_socket_state_t
Connection states.
Definition fb_service.h:94
@ FB_SOCKET_STATE_FLUSHING
Line-oriented or WebSocket session is closing, flushing output.
Definition fb_service.h:99
@ FB_SOCKET_STATE_OPEN
Line-oriented or WebSocket session in process.
Definition fb_service.h:98
@ FB_SOCKET_STATE_TLS_HANDSHAKE
Connection has not yet completed TLS handshake.
Definition fb_service.h:95
@ FB_SOCKET_STATE_GREETING
HTTP/TLS connection is awaiting a request.
Definition fb_service.h:96
@ FB_SOCKET_STATE_CLOSING
Line-oriented or WebSocket connection has finished flushing.
Definition fb_service.h:100
@ FB_SOCKET_STATE_GATHERING_HEADER
HTTP/HTTPS request in process, still reading headering.
Definition fb_service.h:97
fb_socket_type_t
Magic numbers used to differentiate parameter types sent to fb_fprintf.
Definition fb_service.h:86
@ FB_SOCKTYPE_SERVICE
Random numbers.
Definition fb_service.h:87
Football private transport layer declarations.
Connection state information.
Definition fb_service.h:199
int socket
File descriptor for this connection.
Definition fb_service.h:202
void * context
For user use, if desired/needed.
Definition fb_service.h:228
void * relatedObject
C++ object for this connection.
Definition fb_service.h:229
FB_SERVICE * service
Service to which connection belongs.
Definition fb_service.h:201
time_t expiry_time
State: Negotiating, open, flushing, closing, etc.
Definition fb_service.h:204
bool http
Flag set for HTTP connections.
Definition fb_service.h:206
FB_IOQUEUE assembly
Output to websocket, awaiting assembly to a WebSocket packet.
Definition fb_service.h:213
FB_SOCKETTYPE type
Magic number so we know this is a connection.
Definition fb_service.h:200
int domain
Connection domain: PF_INET or PF_INET6.
Definition fb_service.h:217
bool greeted
Did we already get a greeting in ALLOW mode?
Definition fb_service.h:205
FB_IOQUEUE out
Output ready to go out the socket.
Definition fb_service.h:214
time_t next_ping
Time to send next websocket ping.
Definition fb_service.h:216
bool encrypted
Flag set for TLS connections.
Definition fb_service.h:207
char * filename
For file connections.
Definition fb_service.h:224
FB_INPUTBUFFER in
Input buffer.
Definition fb_service.h:215
Events are returned in this structure.
Definition fb_public.h:42
Structure which collects HTTP request information as it is read.
Definition fb_service.h:180
char * filename
Request filename (Service name stripped off if used).
Definition fb_service.h:186
bool invalid
flag set if invalidness was found while reading the header.
Definition fb_service.h:194
char * upgrade_type
Query parameters, if present.
Definition fb_service.h:188
char * http
HTTP version from HEAD or GET request.
Definition fb_service.h:183
bool headonly
flag set for HEAD request
Definition fb_service.h:182
char * language
Accept-Language HTTP request parameter.
Definition fb_service.h:193
bool failure
Web server suffering troubles.
Definition fb_service.h:195
char * host
Requesting host.
Definition fb_service.h:184
char * if_modified_since
Used to support caching via GET requests.
Definition fb_service.h:192
bool unsupported
Unsupported HTTP request (any other than HEAD or GET)
Definition fb_service.h:181
char * service_name
Requested service, if service names in use per service options.
Definition fb_service.h:185
Connection input structure.
Definition fb_service.h:173
size_t size
Number of bytes currently in buffer.
Definition fb_service.h:174
char * message
The buffer.
Definition fb_service.h:176
size_t capacity
Maximum capacity of the buffer.
Definition fb_service.h:175
Queue structure.
Definition fb_service.h:166
Iterator for connections on a football service.
Definition fb_service.h:233
Message structure.
Definition fb_service.h:153
ssize_t length
Length of this message.
Definition fb_service.h:155
char * message
The message.
Definition fb_service.h:156
int usecount
How many message lists this message is currently used in.
Definition fb_service.h:154
Q list structure.
Definition fb_service.h:160
Service options are passed to a new service, defining its behavior.
Definition fb_public.h:75
Football service state structure.
Definition fb_service.h:128
struct fb_connection_t ** connections
Connections to services.
Definition fb_service.h:136
bool shutdown_event_done
Return shutdown event once.
Definition fb_service.h:138
struct fb_service_t * next_reap
For reap queue.
Definition fb_service.h:137
void * relatedObject
C++ object for this service.
Definition fb_service.h:143
FB_SOCKETTYPE type
Magic number so we know this is a service in fb_fprintf.
Definition fb_service.h:129
FB_SOCKETSTATE state
Is the service open or closing?
Definition fb_service.h:130
FB_SERVICE_OPTIONS options
Behavior options.
Definition fb_service.h:131
struct fb_service_t * next_child
Children or next child.
Definition fb_service.h:139
int socket[FB_SOCKET_COUNT]
Socket file descriptors.
Definition fb_service.h:132
FB_SOCKETADDR address[FB_SOCKET_COUNT]
Socket address information.
Definition fb_service.h:133
size_t connection_count
Number of active connections in the collection.
Definition fb_service.h:134
size_t connections_size
Total number of slots in the collection.
Definition fb_service.h:135
Definition fb_transport.h:74
Address of opposing end of a connection.
Definition fb_service.h:114