summaryrefslogtreecommitdiffstats
path: root/include/haproxy/protocol-t.h
blob: b85f29cc03b5b54d461eccfdf30dd88c860c06c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
 * include/haproxy/protocol-t.h
 * This file defines the structures used by generic network protocols.
 *
 * Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, version 2.1
 * exclusively.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _HAPROXY_PROTOCOL_T_H
#define _HAPROXY_PROTOCOL_T_H

#include <sys/types.h>
#include <sys/socket.h>

#include <import/ebtree-t.h>
#include <haproxy/api-t.h>

/* some pointer types referenced below */
struct listener;
struct receiver;
struct connection;

/*
 * Custom network family for str2sa parsing.  Should be ok to do this since
 * sa_family_t is standardized as an unsigned integer
 */
#define AF_CUST_EXISTING_FD  (AF_MAX + 1)
#define AF_CUST_SOCKPAIR     (AF_MAX + 2)
#define AF_CUST_RHTTP_SRV    (AF_MAX + 3)
#define AF_CUST_MAX          (AF_MAX + 4)

/*
 * Test in case AF_CUST_MAX overflows the sa_family_t (unsigned int)
 */
#if (AF_CUST_MAX < AF_MAX)
# error "Can't build on the target system, AF_CUST_MAX overflow"
#endif

/* socket-level protocol types, used for protocol selection */
enum proto_type {
	PROTO_TYPE_STREAM,      /* streaming protocol (like TCP) */
	PROTO_TYPE_DGRAM,       /* datagram protocol (like UDP) */
	PROTO_NUM_TYPES         /* must be the last one */
};

/* max length of a protocol name, including trailing zero */
#define PROTO_NAME_LEN 16

/* flags for ->connect() */
#define CONNECT_HAS_DATA                        0x00000001 /* There's data available to be sent */
#define CONNECT_DELACK_SMART_CONNECT            0x00000002 /* Use a delayed ACK if the backend has tcp-smart-connect */
#define CONNECT_DELACK_ALWAYS                   0x00000004 /* Use a delayed ACK */
#define CONNECT_CAN_USE_TFO                     0x00000008 /* We can use TFO for this connection */

/* Flags for protocol->flags */
#define PROTO_F_REUSEPORT_SUPPORTED             0x00000001 /* SO_REUSEPORT is supported */
#define PROTO_F_REUSEPORT_TESTED                0x00000002 /* SO_REUSEPORT support was tested */

/* protocol families define standard functions acting on a given address family
 * for a socket implementation, such as AF_INET/PF_INET for example.
 */
struct proto_fam {
	char name[PROTO_NAME_LEN];                      /* family name, zero-terminated */
	int sock_domain;				/* socket domain, as passed to socket()   */
	sa_family_t sock_family;			/* socket family, for sockaddr */
	ushort l3_addrlen;				/* layer3 address length, used by hashes */
	socklen_t sock_addrlen;				/* socket address length, used by bind() */
	/* 4-bytes hole here */
	int (*addrcmp)(const struct sockaddr_storage *, const struct sockaddr_storage *); /* compare addresses (like memcmp) */
	int (*bind)(struct receiver *rx, char **errmsg); /* bind a receiver */
	int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve connection's src addr */
	int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve connection's dst addr */
	void (*set_port)(struct sockaddr_storage *, int port);  /* set the port on the address; NULL if not implemented */
};

/* This structure contains all information needed to easily handle a protocol.
 * Its primary goal is to ease listeners maintenance. Specifically, the
 * bind() primitive must be used before any fork(). rx_suspend()/rx_resume()
 * return >0 on success, 0 if rx stopped, -1 on failure to proceed. rx_* may
 * be null if the protocol doesn't provide direct access to the receiver.
 */
struct protocol {
	char name[PROTO_NAME_LEN];			/* protocol name, zero-terminated */
	struct proto_fam *fam;                          /* protocol family */
	int xprt_type;                                  /* transport layer type (PROTO_TYPE_STREAM/PROTO_TYPE_DGRAM) */
	enum proto_type proto_type;                     /* protocol type at the socket layer (PROTO_TYPE_*) */
	int sock_type;					/* socket type, as passed to socket()     */
	int sock_prot;					/* socket protocol, as passed to socket() */

	/* functions acting on the listener */
	void (*add)(struct protocol *p, struct listener *l); /* add a listener for this protocol */
	int (*listen)(struct listener *l, char *errmsg, int errlen); /* start a listener */
	void (*enable)(struct listener *l);             /* enable receipt of new connections */
	void (*disable)(struct listener *l);            /* disable receipt of new connections */
	void (*unbind)(struct listener *l);             /* unbind the listener and possibly its receiver */
	int (*suspend)(struct listener *l);             /* try to suspend the listener */
	int (*resume)(struct listener *l);              /* try to resume a suspended listener */
	struct connection *(*accept_conn)(struct listener *l, int *status); /* accept a new connection */

	/* functions acting on connections */
	void (*ctrl_init)(struct connection *);         /* completes initialization of the connection */
	void (*ctrl_close)(struct connection *);        /* completes release of the connection */
	int (*connect)(struct connection *, int flags); /* connect function if any, see below for flags values */
	int (*drain)(struct connection *);              /* drain pending data; 0=failed, >0=success */
	int (*check_events)(struct connection *conn, int event_type);  /* subscribe to socket events */
	void (*ignore_events)(struct connection *conn, int event_type);  /* unsubscribe from socket events */
	int (*get_src)(struct connection *conn, struct sockaddr *, socklen_t); /* retrieve connection's source address; -1=fail */
	int (*get_dst)(struct connection *conn, struct sockaddr *, socklen_t); /* retrieve connection's dest address; -1=fail */
	int (*set_affinity)(struct connection *conn, int new_tid);

	/* functions acting on the receiver */
	int (*rx_suspend)(struct receiver *rx);         /* temporarily suspend this receiver for a soft restart */
	int (*rx_resume)(struct receiver *rx);          /* try to resume a temporarily suspended receiver */
	void (*rx_enable)(struct receiver *rx);         /* enable receiving on the receiver */
	void (*rx_disable)(struct receiver *rx);        /* disable receiving on the receiver */
	void (*rx_unbind)(struct receiver *rx);         /* unbind the receiver, most often closing the FD */
	int (*rx_listening)(const struct receiver *rx); /* is the receiver listening ? 0=no, >0=OK, <0=unrecoverable */

	/* default I/O handler */
	void (*default_iocb)(int fd);                   /* generic I/O handler (typically accept callback) */

	uint flags;                                     /* flags describing protocol support (PROTO_F_*) */
	uint nb_receivers;                              /* number of receivers (under proto_lock) */
	struct list receivers;				/* list of receivers using this protocol (under proto_lock) */
	struct list list;				/* list of registered protocols (under proto_lock) */
};

#endif /* _HAPROXY_PROTOCOL_T_H */

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */