pianod2
multisource multiuser scriptable networked music player
fb_service.h
Go to the documentation of this file.
1 
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
32 extern "C" {
33 #endif
34 
35 /* Logging facilities */
36 typedef enum fb_log_types_t {
37  FB_LOG_ERROR = 0, /* Nonmaskable */
39  FB_LOG_PARSER = 0x04,
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 
86 typedef enum fb_socket_type_t {
89  FB_SOCKTYPE_USER = 0xa9f7,
90  FB_SOCKTYPE_EVENT = 0xbd53
92 
94 typedef enum fb_socket_state_t {
102 
103 typedef enum fb_socketid_t {
112 
114 typedef 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 
128 struct fb_service_t {
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  */
153 typedef struct fb_message_t {
154  int usecount;
155  ssize_t length;
156  char *message;
158 
160 typedef struct fb_messagelist_t {
164 
166 typedef struct fb_ioqueue_t {
169  ssize_t consumed; /***< Number of bytes consumed in first message. */
171 
173 typedef struct fb_inputbuffer_t {
174  size_t size;
175  size_t capacity;
176  char *message;
178 
180 typedef struct fb_http_request_t {
181  bool unsupported;
182  bool headonly;
183  char *http;
184  char *host;
185  char *service_name;
186  char *filename;
187  char *query_string;
193  char *language;
194  bool invalid;
195  bool failure;
197 
202  int socket;
204  bool greeted;
205  bool http;
206  bool encrypted;
208 #ifdef FB_HAVE_TLS
209  FB_TLS_CONTEXT tls;
210 #endif
215  time_t next_ping;
216  int domain;
217  union {
218  struct sockaddr_in ip4addr;
219 #ifdef HAVE_IPV6
220  struct sockaddr_in6 ip6addr;
221 #endif
223  char *filename;
224 #ifdef FOOTBALL_THREADS
225  pthread_mutex_t mutex;
226 #endif
227  void *context;
229 };
230 
234  ssize_t iteration;
235 };
236 
237 /* Message data management */
238 extern void fb_free_freelists (void);
239 extern FB_MESSAGE *fb_messagealloc(void);
240 extern void fb_messagefree(FB_MESSAGE *freethis);
241 
242 extern FB_MESSAGELIST *fb_qalloc();
243 extern void fb_qfree (FB_MESSAGELIST *freethis);
244 
245 extern bool fb_queue_add (FB_IOQUEUE *queue, FB_MESSAGE *message);
246 extern bool fb_queue_empty (FB_IOQUEUE *q);
247 extern void fb_queue_consume (FB_IOQUEUE *q, size_t consume);
248 extern void fb_queue_destroy (FB_IOQUEUE *q);
249 
250 /* Destroy the service when all connections are closed. */
251 extern void fb_destroy_service (struct fb_service_t *service);
252 extern void fb_schedule_reap (FB_SERVICE *service);
253 
254 /* Transfer service for HELO <svc> or http://my.server/<service> */
255 extern bool fb_transfer_by_name (FB_CONNECTION *connection, const char *name);
256 
257 /* Register/Unregister a connection with the socket manager */
258 extern void fb_queue_event (FB_EVENT *event);
259 extern void fb_dispose_event (FB_EVENT *event);
260 extern bool fb_register (int socket, FB_SOCKETTYPE type, void *thing);
261 extern void fb_unregister (int socket);
262 
263 /* Accept/Close & release a socket and its resources */
265 extern void fb_destroy_connection (FB_CONNECTION *connection);
266 
267 /* Event handling functions */
268 extern bool fb_set_input_buffer_size (FB_CONNECTION *connection, size_t size);
269 extern bool fb_recv_input (FB_CONNECTION *connection, ssize_t byte_count);
270 extern FB_EVENT *fb_read_input (FB_EVENT *event, FB_CONNECTION *connection);
271 extern FB_EVENT *fb_new_connect (FB_EVENT *event, FB_SERVICE *service);
272 extern FB_EVENT *fb_send_output (FB_EVENT *event, FB_CONNECTION *connection);
273 
274 /* HTTP & Websocket support */
275 extern FB_EVENT *fb_read_websocket_input (FB_EVENT *event, FB_CONNECTION *connection);
276 extern bool fb_websocket_ping (FB_CONNECTION *connection);
277 extern bool fb_websocket_announce_close (FB_CONNECTION *connection);
278 extern bool fb_websocket_encode (FB_CONNECTION *connection);
279 extern void fb_destroy_httprequest (FB_HTTPREQUEST *request);
280 extern void fb_collect_http_request (FB_EVENT *event, FB_HTTPREQUEST *request);
281 extern void fb_collect_http_parameter (char *line, FB_HTTPREQUEST *request);
282 extern bool fb_http_command (const char *command);
283 extern FB_EVENT *fb_execute_http_request (FB_EVENT *event, FB_CONNECTION *connection);
284 
285 /* Utility/TLS functions */
286 extern int fb_create_argv (const char *commandline, char ***result);
287 extern int fb_create_argv_from_query_string (const char *query_string, char ***result, char ***remainders);
288 extern void fb_destroy_argv (char **argv);
289 extern const char *fb_connection_info (FB_CONNECTION *connection);
290 
291 /* Enabling/disabling events for the socket manager */
292 extern void fb_set_buffering (int socket_fd, bool enable);
293 extern void fb_set_readable (int socket, bool enable);
294 extern void fb_set_writable (int socket, bool enable);
295 
296 #define FAR_FUTURE ((time_t) (((time_t) 0x7fffffff) << ((sizeof (time_t) - 4) * 8)))
297 
298 #ifdef __cplusplus
299 }
300 #endif
301 
Football public declarations.
bool fb_transfer_by_name(FB_CONNECTION *connection, const char *name)
Definition: fb_service.c:494
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_destroy_argv(char **argv)
Definition: fb_utility.c:154
bool fb_recv_input(FB_CONNECTION *connection, ssize_t byte_count)
Definition: fb_event.c:352
void fb_free_freelists(void)
Definition: fb_message.c:30
void fb_destroy_connection(FB_CONNECTION *connection)
Definition: fb_service.c:516
enum fb_socketid_t FB_SOCKETID
void fb_set_readable(int socket, bool enable)
Definition: fb_socketmgr.c:298
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.
fb_socketid_t
Definition: fb_service.h:103
@ FB_SOCKET_HTTP_IP6
Definition: fb_service.h:107
@ FB_SOCKET_COUNT
Definition: fb_service.h:110
@ FB_SOCKET_HTTPS_IP4
Definition: fb_service.h:108
@ FB_SOCKET_LINE_IP6
Definition: fb_service.h:105
@ FB_SOCKET_HTTPS_IP6
Definition: fb_service.h:109
@ FB_SOCKET_HTTP_IP4
Definition: fb_service.h:106
@ FB_SOCKET_LINE_IP4
Definition: fb_service.h:104
void fb_queue_event(FB_EVENT *event)
Definition: fb_socketmgr.c:98
void fb_collect_http_parameter(char *line, FB_HTTPREQUEST *request)
Definition: fb_http.c:972
FB_EVENT * fb_read_input(FB_EVENT *event, FB_CONNECTION *connection)
Definition: fb_event.c:464
union fb_socketaddr_t FB_SOCKETADDR
Address of opposing end of a connection.
struct fb_ioqueue_t FB_IOQUEUE
Queue structure.
bool fb_set_input_buffer_size(FB_CONNECTION *connection, size_t size)
Definition: fb_event.c:333
void fb_queue_destroy(FB_IOQUEUE *q)
Definition: fb_message.c:184
FB_EVENT * fb_send_output(FB_EVENT *event, FB_CONNECTION *connection)
Definition: fb_event.c:266
void fb_qfree(FB_MESSAGELIST *freethis)
Definition: fb_message.c:110
void fb_destroy_httprequest(FB_HTTPREQUEST *request)
Definition: fb_http.c:837
FB_CONNECTION * fb_accept_connection(FB_SERVICE *service, FB_SOCKETID id)
Definition: fb_service.c:389
FB_EVENT * fb_new_connect(FB_EVENT *event, FB_SERVICE *service)
Definition: fb_event.c:574
fb_log_types_t
Definition: fb_service.h:36
@ FB_LOG_CONN_ERROR
Definition: fb_service.h:42
@ FB_LOG_PARSER
Definition: fb_service.h:39
@ FB_LOG_CONN_STATUS
Definition: fb_service.h:41
@ FB_LOG_IO_TRACE
Definition: fb_service.h:40
@ FB_LOG_TLS_STATUS
Definition: fb_service.h:43
@ FB_LOG_ERROR
Definition: fb_service.h:37
@ FB_LOG_HTTP_TRAFFIC
Definition: fb_service.h:47
@ FB_LOG_WARNING
Definition: fb_service.h:38
@ FB_LOG_TLS_ERROR
Definition: fb_service.h:44
@ FB_LOG_HTTP_STATUS
Definition: fb_service.h:45
@ FB_LOG_HTTP_ERROR
Definition: fb_service.h:46
void fb_destroy_service(struct fb_service_t *service)
Definition: fb_service.c:246
enum fb_log_types_t FB_LOG_TYPE
void fb_messagefree(FB_MESSAGE *freethis)
Definition: fb_message.c:71
void fb_collect_http_request(FB_EVENT *event, FB_HTTPREQUEST *request)
Definition: fb_http.c:910
struct fb_message_t FB_MESSAGE
Message structure.
void fb_dispose_event(FB_EVENT *event)
Definition: fb_socketmgr.c:109
void fb_schedule_reap(FB_SERVICE *service)
Definition: fb_socketmgr.c:85
bool fb_queue_empty(FB_IOQUEUE *q)
Definition: fb_message.c:127
FB_EVENT * fb_read_websocket_input(FB_EVENT *event, FB_CONNECTION *connection)
Definition: fb_http.c:550
bool fb_http_command(const char *command)
Definition: fb_http.c:1008
bool fb_websocket_announce_close(FB_CONNECTION *connection)
Definition: fb_http.c:679
bool fb_websocket_encode(FB_CONNECTION *connection)
Definition: fb_http.c:693
const char * fb_connection_info(FB_CONNECTION *connection)
Definition: fb_utility.c:85
enum fb_socket_type_t FB_SOCKETTYPE
Magic numbers used to differentiate parameter types sent to fb_fprintf.
FB_MESSAGE * fb_messagealloc(void)
Definition: fb_message.c:51
bool fb_queue_add(FB_IOQUEUE *queue, FB_MESSAGE *message)
Definition: fb_message.c:138
int fb_create_argv_from_query_string(const char *query_string, char ***result, char ***remainders)
Definition: fb_utility.c:263
struct fb_http_request_t FB_HTTPREQUEST
Structure which collects HTTP request information as it is read.
void fb_set_buffering(int socket_fd, bool enable)
Definition: fb_socketmgr.c:277
void fb_queue_consume(FB_IOQUEUE *q, size_t consume)
Definition: fb_message.c:162
void fb_set_writable(int socket, bool enable)
Definition: fb_socketmgr.c:290
FB_EVENT * fb_execute_http_request(FB_EVENT *event, FB_CONNECTION *connection)
Definition: fb_http.c:1493
struct fb_messagelist_t FB_MESSAGELIST
Q list structure.
FB_MESSAGELIST * fb_qalloc()
Definition: fb_message.c:91
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
bool fb_websocket_ping(FB_CONNECTION *connection)
Definition: fb_http.c:665
fb_socket_type_t
Magic numbers used to differentiate parameter types sent to fb_fprintf.
Definition: fb_service.h:86
@ FB_SOCKTYPE_EVENT
Definition: fb_service.h:90
@ FB_SOCKTYPE_CONNECTION
Definition: fb_service.h:88
@ FB_SOCKTYPE_SERVICE
Random numbers.
Definition: fb_service.h:87
@ FB_SOCKTYPE_USER
Definition: fb_service.h:89
int fb_create_argv(const char *commandline, char ***result)
Definition: fb_utility.c:172
Football private transport layer declarations.
Connection state information.
Definition: fb_service.h:199
struct sockaddr_in ip4addr
Definition: fb_service.h:218
int socket
File descriptor for this connection.
Definition: fb_service.h:202
void * context
For user use, if desired/needed.
Definition: fb_service.h:227
void * relatedObject
C++ object for this connection.
Definition: fb_service.h:228
FB_SOCKETSTATE state
Definition: fb_service.h:203
union fb_connection_t::@1 origin
FB_SERVICE * service
Service to which connection belongs.
Definition: fb_service.h:201
bool http
Flag set for HTTP connections.
Definition: fb_service.h:205
FB_IOQUEUE assembly
Output to websocket, awaiting assembly to a WebSocket packet.
Definition: fb_service.h:212
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:216
bool greeted
State: Negotiating, open, flushing, closing, etc.
Definition: fb_service.h:204
FB_IOQUEUE out
Output ready to go out the socket.
Definition: fb_service.h:213
FB_HTTPREQUEST request
Definition: fb_service.h:211
time_t next_ping
Time to send next websocket ping.
Definition: fb_service.h:215
bool encrypted
Flag set for TLS connections.
Definition: fb_service.h:206
char * filename
For file connections.
Definition: fb_service.h:223
const FB_TRANSPORT_FUNCS * transport
Definition: fb_service.h:207
FB_INPUTBUFFER in
Input buffer.
Definition: fb_service.h:214
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
char * websocket_version
Definition: fb_service.h:191
char * query_string
Definition: fb_service.h:187
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 * websocket_key
Definition: fb_service.h:189
char * websocket_protocol
Definition: fb_service.h:190
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
FB_MESSAGELIST * last
Definition: fb_service.h:168
FB_MESSAGELIST * first
Definition: fb_service.h:167
ssize_t consumed
Definition: fb_service.h:169
Iterator for connections on a football service.
Definition: fb_service.h:232
FB_SERVICE * service
Definition: fb_service.h:233
ssize_t iteration
Definition: fb_service.h:234
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
struct fb_messagelist_t * next
Definition: fb_service.h:161
FB_MESSAGE * message
Definition: fb_service.h:162
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
struct sockaddr_in ip4
Definition: fb_service.h:115