connection.h revision 4487c66123ca4830f8afbf4efcd7a260848d0e05
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef CONNECTION_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define CONNECTION_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "net.h"
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct connection;
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenenum connection_behavior {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen CONNECTION_BEHAVIOR_DESTROY = 0,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen CONNECTION_BEHAVIOR_ALLOW
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen};
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainenenum connection_disconnect_reason {
3ed2d0f6b5e67e2663d44489d9da3176823789a8Timo Sirainen /* not disconnected yet */
65f8fb656051f1059f7b5a2da9c5555adcc30439Timo Sirainen CONNECTION_DISCONNECT_NOT = 0,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen /* normal requested disconnection */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen CONNECTION_DISCONNECT_DEINIT,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen /* input buffer full */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen CONNECTION_DISCONNECT_BUFFER_FULL,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen /* connection got disconnected */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen CONNECTION_DISCONNECT_CONN_CLOSED,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen /* connect() timed out */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen CONNECTION_DISCONNECT_CONNECT_TIMEOUT,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* remote didn't send input */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen CONNECTION_DISCONNECT_IDLE_TIMEOUT
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstruct connection_vfuncs {
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen void (*destroy)(struct connection *conn);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* For UNIX socket clients this gets called immediately (unless
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen delayed_unix_client_connected_callback=TRUE) with success=TRUE,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen for IP connections it gets called later:
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen If connect() fails, sets success=FALSE and errno. Streams aren't
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen initialized in that situation either. destroy() is called after
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen the callback. */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen void (*client_connected)(struct connection *conn, bool success);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen /* implement one of the input*() methods.
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen They return 1 = ok, continue. 0 = ok, but stop processing more
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen lines, -1 = error, disconnect the client. */
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen void (*input)(struct connection *conn);
3e564425db51f3921ce4de11859777135fdedd15Timo Sirainen int (*input_line)(struct connection *conn, const char *line);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen int (*input_args)(struct connection *conn, const char *const *args);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen};
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstruct connection_settings {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const char *service_name_in;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const char *service_name_out;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen unsigned int major_version, minor_version;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen unsigned int client_connect_timeout_msecs;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen unsigned int input_idle_timeout_secs;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen size_t input_max_size;
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen size_t output_max_size;
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen enum connection_behavior input_full_behavior;
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen bool client;
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen bool dont_send_version;
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* Don't call client_connected() immediately on
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen connection_client_connect() with UNIX sockets. This is mainly
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen to make the functionality identical with inet sockets, which may
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen simplify the calling code. */
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen bool delayed_unix_client_connected_callback;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* If connect() to UNIX socket fails with EAGAIN, retry for this many
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen milliseconds before giving up (0 = try once) */
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen unsigned int unix_client_connect_msecs;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen};
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct connection {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct connection *prev, *next;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct connection_list *list;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen char *name;
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen int fd_in, fd_out;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen struct io *io;
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen struct istream *input;
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen struct ostream *output;
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen struct timeout *to;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen time_t last_input;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen /* for IP client: */
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen struct ip_addr ip;
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen unsigned int port;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
70ead6466f9baa8294e71fc2fba0a4f54f488b5eTimo Sirainen /* received minor version */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen unsigned int minor_version;
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen enum connection_disconnect_reason disconnect_reason;
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int version_received:1;
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen};
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainenstruct connection_list {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct connection *connections;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen unsigned int connections_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct connection_settings set;
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen struct connection_vfuncs v;
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen};
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainenvoid connection_init_server(struct connection_list *list,
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen struct connection *conn, const char *name,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen int fd_in, int fd_out);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenvoid connection_init_client_ip(struct connection_list *list,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct connection *conn,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen const struct ip_addr *ip, unsigned int port);
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainenvoid connection_init_client_unix(struct connection_list *list,
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen struct connection *conn, const char *path);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenvoid connection_init_from_streams(struct connection_list *list,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen struct connection *conn, const char *name,
e03d986a74128f5ba30fcfda9f6e36578f5d8decTimo Sirainen struct istream *input, struct ostream *output);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenint connection_client_connect(struct connection *conn);
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenvoid connection_disconnect(struct connection *conn);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainenvoid connection_deinit(struct connection *conn);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen/* Returns -1 = disconnected, 0 = nothing new, 1 = something new.
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen If input_full_behavior is ALLOW, may return also -2 = buffer full. */
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainenint connection_input_read(struct connection *conn);
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen/* Verify that VERSION input matches what we expect. */
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainenint connection_verify_version(struct connection *conn, const char *const *args);
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen/* Returns human-readable reason for why connection was disconnected. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char *connection_disconnect_reason(struct connection *conn);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainenvoid connection_switch_ioloop(struct connection *conn);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainenstruct connection_list *
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainenconnection_list_init(const struct connection_settings *set,
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen const struct connection_vfuncs *vfuncs);
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainenvoid connection_list_deinit(struct connection_list **list);
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainenvoid connection_input_default(struct connection *conn);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainenint connection_input_line_default(struct connection *conn, const char *line);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#endif
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen