Football TLS Encryption Support =============================== While at this, we want to get rid of the half-`read()`/`write()` direct, half standard I/O. Frankly, it doesn't look like it should work as coded. * For portability, move to `recv()` and `send()` instead of `read()`/`write()`. * FILE I/O & fgetln will be retained for read-from-files only. Because we're relying on select(), we MUST not buffer anything when doing line-based I/O lest connections stall because their input is buffered and it appears they have nothing to say. This sort of sucks, but in reality it's already happening under the hood. It'll just become obvious we're doing it. Service changes --------------- Two new ports: IP4 & IP6 HTTP encrypted Connection changes ------------------ New flag: Encrypted Code changes ------------ * `fb_send_output` will have to check the connection encryption flag when sending data. If encrypted, use `gnutls_record_send`, if not encrypted, use `send`. * `fb_get_http_bytes` will need a similar check. If encrypted, it will use `gnutls_record_recv`, if not encrypted use `recv`. * `fb_read_line_input` will need major rework; see details below. ### `fb_read_line_input` If `connection->file`, then this is a file, not a socket; it will not be encrypted. Use fgetln(). On entry, we know there is input ready because select() sent us here. However, there is no guarantee we will receive a full line. We will need to add a buffer, similar to the HTTP solution, to address the mysteriously operational code. The buffer size management code from `fb_get_http_bytes` will become a new function, `fb_expect_input_buffer_size` that will ensure the input buffer is meets needs and reallocate as needed. Now to read from the file: while (read a byte to the buffer) { if (byte was a newline) { return resulting event; } } if (reason for failure was no data available) /* EAGAIN, EINTR or corresponding GNUTLS versions */ return NULL } Otherwise: Connection error, initiate closure. return NULL If no messages are available at the socket, the receive call waits for a message to arrive, unless the socket is nonblocking (see fcntl(2)) in which case the value -1 is returned and the external variable errno set to EAGAIN. Also consider GNUTLS_E_INTERRUPTED as normal. It is probably easiest to implement the aforementioned loop twice, once for unencrypted receive and once for TLS because the semantics of GNUTLS library are subtly different (-1 & errno vs. negative value indicating error code).