connection.h revision a5b64f1abb1cb0a9718d5bf7f0ae808072237259
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen#ifndef CONNECTION_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define CONNECTION_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e05a4c4136fec723f019bee8383103080203f127Timo Sirainen#include "net.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct connection;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenenum connection_behavior {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen CONNECTION_BEHAVIOR_DESTROY = 0,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen CONNECTION_BEHAVIOR_ALLOW
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen};
e05a4c4136fec723f019bee8383103080203f127Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenenum connection_disconnect_reason {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* not disconnected yet */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen CONNECTION_DISCONNECT_NOT = 0,
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen /* normal requested disconnection */
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen CONNECTION_DISCONNECT_DEINIT,
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen /* input buffer full */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen CONNECTION_DISCONNECT_BUFFER_FULL,
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen /* connection got disconnected */
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen CONNECTION_DISCONNECT_CONN_CLOSED,
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen /* connect() timed out */
d22301419109ed4a38351715e6760011421dadecTimo Sirainen CONNECTION_DISCONNECT_CONNECT_TIMEOUT,
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen /* remote didn't send input */
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen CONNECTION_DISCONNECT_IDLE_TIMEOUT
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen};
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainenstruct connection_vfuncs {
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen void (*destroy)(struct connection *conn);
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen /* For UNIX socket clients this gets called immediately (unless
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen delayed_unix_client_connected_callback=TRUE) with success=TRUE,
01937f71b3ae0d5b30b813372f44a3e7e86c89dcTimo Sirainen for IP connections it gets called later:
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen If connect() fails, sets success=FALSE and errno. Streams aren't
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen initialized in that situation either. destroy() is called after
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen the callback. */
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen void (*client_connected)(struct connection *conn, bool success);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen /* implement one of the input*() methods.
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen They return 1 = ok, continue. 0 = ok, but stop processing more
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen lines, -1 = error, disconnect the client. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen void (*input)(struct connection *conn);
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen int (*input_line)(struct connection *conn, const char *line);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen int (*input_args)(struct connection *conn, const char *const *args);
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen};
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct connection_settings {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *service_name_in;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *service_name_out;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen unsigned int major_version, minor_version;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen unsigned int client_connect_timeout_msecs;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen unsigned int input_idle_timeout_secs;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen size_t input_max_size;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen size_t output_max_size;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen enum connection_behavior input_full_behavior;
01937f71b3ae0d5b30b813372f44a3e7e86c89dcTimo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen bool client;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen bool dont_send_version;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen /* By default when only input_args() is used, or when
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen connection_input_line_default() is used, empty lines aren't allowed
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen since it would result in additional args[0] == NULL check. Setting
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen this to TRUE passes it through instead of logging an error. */
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen bool allow_empty_args_input;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen /* Don't call client_connected() immediately on
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen connection_client_connect() with UNIX sockets. This is mainly
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen to make the functionality identical with inet sockets, which may
a341c4cdbd4b93ba479f465ad3f569dc82f57312Timo Sirainen simplify the calling code. */
013e3b3942e9550fde619a0b3ce6bdd04edc4268Timo Sirainen bool delayed_unix_client_connected_callback;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen /* If connect() to UNIX socket fails with EAGAIN, retry for this many
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen milliseconds before giving up (0 = try once) */
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen unsigned int unix_client_connect_msecs;
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen};
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen
9293bf90039454f47e94e4ba3722a775cfa7d25cTimo Sirainenstruct connection {
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen struct connection *prev, *next;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen struct connection_list *list;
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen char *name;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen int fd_in, fd_out;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen struct io *io;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen struct istream *input;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen struct ostream *output;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen struct timeout *to;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen time_t last_input;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen struct timeval last_input_tv;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen struct timeval connect_started;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen struct timeval connect_finished;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen /* for IP client: */
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen struct ip_addr ip;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen in_port_t port;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen /* received minor version */
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen unsigned int minor_version;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen enum connection_disconnect_reason disconnect_reason;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen bool version_received:1;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen};
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainenstruct connection_list {
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen struct connection *connections;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen unsigned int connections_count;
4d2211dac61c615c5bdfd501ea54d46c89d41b0fTimo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen struct connection_settings set;
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen struct connection_vfuncs v;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen};
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainenvoid connection_init_server(struct connection_list *list,
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen struct connection *conn, const char *name,
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen int fd_in, int fd_out);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainenvoid connection_init_client_ip(struct connection_list *list,
741d705983e10046f07ef372b760bcdd169b068aTimo Sirainen struct connection *conn,
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen const struct ip_addr *ip, in_port_t port);
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainenvoid connection_init_client_unix(struct connection_list *list,
6d931bbce16786df431e9ae8201a78a95084316dTimo Sirainen struct connection *conn, const char *path);
6d931bbce16786df431e9ae8201a78a95084316dTimo Sirainenvoid connection_init_from_streams(struct connection_list *list,
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen struct connection *conn, const char *name,
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen struct istream *input, struct ostream *output);
4d2211dac61c615c5bdfd501ea54d46c89d41b0fTimo Sirainen
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainenint connection_client_connect(struct connection *conn);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainenvoid connection_disconnect(struct connection *conn);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainenvoid connection_deinit(struct connection *conn);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen/* Returns -1 = disconnected, 0 = nothing new, 1 = something new.
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen If input_full_behavior is ALLOW, may return also -2 = buffer full. */
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainenint connection_input_read(struct connection *conn);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen/* Verify that VERSION input matches what we expect. */
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainenint connection_verify_version(struct connection *conn, const char *const *args);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen
741d705983e10046f07ef372b760bcdd169b068aTimo Sirainen/* Returns human-readable reason for why connection was disconnected. */
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainenconst char *connection_disconnect_reason(struct connection *conn);
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen/* Returns human-readable reason for why connection timed out,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen e.g. "No input for 10.023 secs". */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char *connection_input_timeout_reason(struct connection *conn);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid connection_switch_ioloop(struct connection *conn);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainenstruct connection_list *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconnection_list_init(const struct connection_settings *set,
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen const struct connection_vfuncs *vfuncs);
741d705983e10046f07ef372b760bcdd169b068aTimo Sirainenvoid connection_list_deinit(struct connection_list **list);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainenvoid connection_input_default(struct connection *conn);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint connection_input_line_default(struct connection *conn, const char *line);
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen#endif
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen