2005-09-15 09:58:31 -04:00
|
|
|
#ifndef EL__NETWORK_SOCKET_H
|
|
|
|
#define EL__NETWORK_SOCKET_H
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
|
|
#include <sys/socket.h> /* OS/2 needs this after sys/types.h */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "network/state.h"
|
|
|
|
|
2020-10-05 14:14:55 -04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2005-09-15 09:58:31 -04:00
|
|
|
struct connect_info;
|
|
|
|
struct read_buffer;
|
|
|
|
struct socket;
|
|
|
|
struct uri;
|
|
|
|
|
|
|
|
|
|
|
|
/* Use internally for error return values. */
|
|
|
|
enum socket_error {
|
2008-08-03 08:24:26 -04:00
|
|
|
SOCKET_SYSCALL_ERROR = -1, /* Retry with connection_state_for_errno(errno). */
|
|
|
|
SOCKET_INTERNAL_ERROR = -2, /* Stop with connection_state(errno). */
|
2005-09-15 09:58:31 -04:00
|
|
|
SOCKET_SSL_WANT_READ = -3, /* Try to read some more. */
|
|
|
|
SOCKET_CANT_READ = -4, /* Retry with S_CANT_READ state. */
|
|
|
|
SOCKET_CANT_WRITE = -5, /* Retry with S_CANT_WRITE state. */
|
|
|
|
};
|
|
|
|
|
|
|
|
enum socket_state {
|
|
|
|
/* If a zero-byte message is read prematurely the connection will be
|
|
|
|
* retried with error state S_CANT_READ. */
|
|
|
|
SOCKET_RETRY_ONCLOSE,
|
|
|
|
/* If a zero-byte message is read flush the remaining bytes in the
|
|
|
|
* buffer and tell the protocol handler to end the reading by calling
|
|
|
|
* read_buffer->done(). */
|
|
|
|
SOCKET_END_ONCLOSE,
|
|
|
|
/* Used for signaling to protocols - via the read_buffer->done()
|
|
|
|
* callback - that a zero-byte message was read. */
|
|
|
|
SOCKET_CLOSED,
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef void (*socket_read_T)(struct socket *, struct read_buffer *);
|
|
|
|
typedef void (*socket_write_T)(struct socket *);
|
|
|
|
typedef void (*socket_connect_T)(struct socket *);
|
2008-08-03 08:24:26 -04:00
|
|
|
typedef void (*socket_operation_T)(struct socket *, struct connection_state);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
struct socket_operations {
|
|
|
|
/* Report change in the state of the socket. */
|
|
|
|
socket_operation_T set_state;
|
|
|
|
/* Reset the timeout for the socket. */
|
|
|
|
socket_operation_T set_timeout;
|
2008-01-26 23:09:18 -05:00
|
|
|
/* Some system related error occurred; advise to reconnect. */
|
2005-09-15 09:58:31 -04:00
|
|
|
socket_operation_T retry;
|
2008-01-26 23:09:18 -05:00
|
|
|
/* A fatal error occurred, like a memory allocation failure; advise to
|
2005-09-15 09:58:31 -04:00
|
|
|
* abort the connection. */
|
|
|
|
socket_operation_T done;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct read_buffer {
|
|
|
|
/* A routine called *each time new data comes in*, therefore
|
|
|
|
* usually many times, not only when all the data arrives. */
|
|
|
|
socket_read_T done;
|
|
|
|
|
|
|
|
int length;
|
|
|
|
int freespace;
|
|
|
|
|
2021-01-02 10:20:27 -05:00
|
|
|
char data[1]; /* must be at end of struct */
|
2005-09-15 09:58:31 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct socket {
|
|
|
|
/* The socket descriptor */
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
/* Somewhat read-specific socket state management and signaling. */
|
|
|
|
enum socket_state state;
|
|
|
|
|
|
|
|
/* Information for resolving the connection with which the socket is
|
|
|
|
* associated. */
|
|
|
|
void *conn;
|
|
|
|
|
|
|
|
/* Information used during the connection establishing phase. */
|
|
|
|
struct connect_info *connect_info;
|
|
|
|
|
|
|
|
/* Use for read and write buffers. */
|
|
|
|
struct read_buffer *read_buffer;
|
|
|
|
void *write_buffer;
|
|
|
|
|
|
|
|
/* Callbacks to the connection management: */
|
|
|
|
struct socket_operations *ops;
|
|
|
|
|
|
|
|
/* Used by the request/response interface for saving the read_done
|
|
|
|
* operation. */
|
|
|
|
socket_read_T read_done;
|
|
|
|
|
|
|
|
/* For connections using SSL this is in fact (ssl_t *), but we don't
|
|
|
|
* want to know. Noone cares and inclusion of SSL header files costs a
|
|
|
|
* lot of compilation time. --pasky */
|
|
|
|
void *ssl;
|
|
|
|
|
2006-01-04 12:06:53 -05:00
|
|
|
unsigned int protocol_family:1; /* EL_PF_INET, EL_PF_INET6 */
|
2005-09-15 09:58:31 -04:00
|
|
|
unsigned int need_ssl:1; /* If the socket needs SSL support */
|
|
|
|
unsigned int no_tls:1; /* Internal SSL flag. */
|
2008-07-26 18:24:36 -04:00
|
|
|
unsigned int set_no_tls:1; /* Was the blacklist checked yet? */
|
2005-09-15 09:58:31 -04:00
|
|
|
unsigned int duplex:1; /* Allow simultaneous reads & writes. */
|
2017-07-23 08:33:40 -04:00
|
|
|
unsigned int verify:1; /* Whether to verify certificates */
|
2005-09-15 09:58:31 -04:00
|
|
|
};
|
|
|
|
|
2006-01-04 12:06:53 -05:00
|
|
|
#define EL_PF_INET 0
|
|
|
|
#define EL_PF_INET6 1
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
/* Socket management: */
|
|
|
|
|
|
|
|
/* Allocate and setup a socket. */
|
|
|
|
struct socket *init_socket(void *conn, struct socket_operations *ops);
|
|
|
|
|
|
|
|
/* Reset a socket so it can be reused. XXX: Does not free() it! */
|
|
|
|
void done_socket(struct socket *socket);
|
|
|
|
|
|
|
|
/* Closes socket if open and clear any associated handlers. */
|
|
|
|
void close_socket(struct socket *socket);
|
|
|
|
|
|
|
|
/* Timeout handler. Will try to reconnect if possible. */
|
|
|
|
void timeout_socket(struct socket *socket);
|
|
|
|
|
|
|
|
|
|
|
|
/* Connection establishing: */
|
|
|
|
|
|
|
|
/* End successful connect() attempt to socket. */
|
|
|
|
void complete_connect_socket(struct socket *socket, struct uri *uri,
|
|
|
|
socket_connect_T done);
|
|
|
|
|
|
|
|
/* Establish connection with the host and port in @uri. Storing the socket
|
|
|
|
* descriptor in @socket. When the connection has been established the @done
|
|
|
|
* callback will be run. @no_cache specifies whether the DNS cache should be
|
|
|
|
* ignored. */
|
|
|
|
void make_connection(struct socket *socket, struct uri *uri,
|
|
|
|
socket_connect_T connect_done, int no_cache);
|
|
|
|
|
|
|
|
/* Creates and returns a listening socket in the same IP family as the passed
|
|
|
|
* ctrl_socket and stores info about the created socket in @addr. @ctrl_socket
|
|
|
|
* is used for getting bind() information. */
|
|
|
|
int get_pasv_socket(struct socket *ctrl_socket, struct sockaddr_storage *addr);
|
|
|
|
|
|
|
|
/* Try to connect to the next available address or force the connection to retry
|
|
|
|
* if all has already been tried. Updates the connection state to
|
|
|
|
* @connection_state. */
|
2008-08-03 08:24:26 -04:00
|
|
|
void connect_socket(struct socket *socket, struct connection_state state);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
/* Used by the SSL layer when negotiating. */
|
|
|
|
void dns_exception(struct socket *socket);
|
|
|
|
|
|
|
|
|
|
|
|
/* Reading and writing to sockets: */
|
|
|
|
|
|
|
|
/* Reads data from @socket into @buffer. Calls @done each time new data is
|
|
|
|
* ready. */
|
|
|
|
void read_from_socket(struct socket *socket, struct read_buffer *buffer,
|
2008-08-03 08:24:26 -04:00
|
|
|
struct connection_state state, socket_read_T done);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
/* Writes @datalen bytes from @data buffer to the passed @socket. When all data
|
|
|
|
* is written the @done callback will be called. */
|
|
|
|
void write_to_socket(struct socket *socket,
|
2021-01-02 10:20:27 -05:00
|
|
|
char *data, int datalen,
|
2008-08-03 08:24:26 -04:00
|
|
|
struct connection_state state, socket_write_T write_done);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
/* Send request and get response. */
|
2021-01-02 10:20:27 -05:00
|
|
|
void request_from_socket(struct socket *socket, char *data, int datalen,
|
2008-08-03 08:24:26 -04:00
|
|
|
struct connection_state state, enum socket_state sock_state,
|
2005-09-15 09:58:31 -04:00
|
|
|
socket_read_T read_done);
|
|
|
|
|
|
|
|
/* Initialize a read buffer. */
|
|
|
|
struct read_buffer *alloc_read_buffer(struct socket *socket);
|
|
|
|
|
|
|
|
/* Remove @bytes number of bytes from @buffer. */
|
|
|
|
void kill_buffer_data(struct read_buffer *buffer, int bytes);
|
|
|
|
|
2020-10-05 14:14:55 -04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-09-15 09:58:31 -04:00
|
|
|
#endif
|