File: socket.h

package info (click to toggle)
bird3 3.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,600 kB
  • sloc: ansic: 85,199; sh: 3,807; perl: 3,484; lex: 976; python: 726; makefile: 527; xml: 520; sed: 13
file content (231 lines) | stat: -rw-r--r-- 9,181 bytes parent folder | download | duplicates (2)
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/*
 *	BIRD Socket Interface
 *
 *	(c) 1998--2004 Martin Mares <mj@ucw.cz>
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#ifndef _BIRD_SOCKET_H_
#define _BIRD_SOCKET_H_

#include <errno.h>

#include "lib/resource.h"
#include "lib/event.h"
#ifdef HAVE_LIBSSH
#define LIBSSH_LEGACY_0_4
#include <libssh/libssh.h>
#endif

#ifdef HAVE_LIBSSH
struct ssh_sock {
    const char *username;		/* (Required) SSH user name */
    const char *server_hostkey_path;	/* (Optional) Filepath to the SSH public key of remote side, can be knownhost file */
    const char *client_privkey_path;	/* (Optional) Filepath to the SSH private key of BIRD */
    const char *subsystem;		/* (Optional) Name of SSH subsytem */
    ssh_session session;		/* Internal */
    ssh_channel channel;		/* Internal */
    int state;				/* Internal */
#define SK_SSH_CONNECT		0	/* Start state */
#define SK_SSH_SERVER_KNOWN	1	/* Internal */
#define SK_SSH_USERAUTH		2	/* Internal */
#define SK_SSH_CHANNEL		3	/* Internal */
#define SK_SSH_SESSION		4	/* Internal */
#define SK_SSH_SUBSYSTEM 	5	/* Internal */
#define SK_SSH_ESTABLISHED	6	/* Final state */
};
#endif

struct ao_key
{
  int send_id;
  int recv_id;
  const char *key;
  uint keylen;
  int algorithm;
  int preference;
};

struct ao_config
{
  struct ao_key key;
  struct ao_config *next;
};

struct ao_info
{
  int current_key;
  int rnext_key;
  u64 pkt_good;
  u64 pkt_bad;
};

#define AO_MAX_KEY_LENGTH	80	/* See sysdep/linux/tcp-ao.h */

typedef struct birdsock {
  resource r;
  pool *pool;				/* Pool where incoming connections should be allocated (for SK_xxx_PASSIVE) */
  int type;				/* Socket type */
  int subtype;				/* Socket subtype */
  void *data;				/* User data */
  ip_addr saddr, daddr;			/* IPA_NONE = unspecified */
  const char *host;			/* Alternative to daddr, NULL = unspecified */
  uint sport, dport;			/* 0 = unspecified (for IP: protocol type) */
  int tos;				/* TOS / traffic class, -1 = default */
  int priority;				/* Local socket priority, -1 = default */
  int ttl;				/* Time To Live, -1 = default */
  u32 flags;
  struct iface *iface;			/* Interface; specify this for broad/multicast sockets */
  struct iface *vrf;			/* Related VRF instance, NULL if global */

  byte *rbuf, *rpos;			/* NULL=allocate automatically */
  uint fast_rx;				/* RX has higher priority in event loop */
  uint rbsize;
  int (*rx_hook)(struct birdsock *, uint size); /* NULL=receiving turned off, returns 1 to clear rx buffer */

  byte *tbuf, *tpos;			/* NULL=allocate automatically */
  byte *ttx;				/* Internal */
  uint tbsize;
  void (*tx_hook)(struct birdsock *);

  void (*err_hook)(struct birdsock *, int); /* errno or zero if EOF */

  /* Information about received datagrams (UDP, RAW), valid in rx_hook */
  ip_addr faddr, laddr;			/* src (From) and dst (Local) address of the datagram */
  uint fport;				/* src port of the datagram */
  uint lifindex;			/* local interface that received the datagram */
  /* laddr and lifindex are valid only if SKF_LADDR_RX flag is set to request it */

  int af;				/* System-dependend adress family (e.g. AF_INET) */
  int fd;				/* System-dependent data */
  int index;				/* Index in poll buffer */
  int rcv_ttl;				/* TTL of last received datagram */
  node n;
  void *rbuf_alloc, *tbuf_alloc;
  const char *password;			/* Password for MD5 authentication (for SK_TCP_ACTIVE) */
  const struct ao_key **ao_keys_init;	/* Keys for TCP-AO authentication (for SK_TCP_ACTIVE) */
  int ao_keys_num;			/* Number of keys in ao_keys_init */
  // int use_ao;			/* This is the only reliable flag saying whether the socket uses TCP-AO */
  const char *err;			/* Error message */
  struct ssh_sock *ssh;			/* Used in SK_SSH */
  struct birdloop *loop;		/* BIRDLoop owning this socket */
} sock;

sock *sock_new(pool *);			/* Allocate new socket */
#define sk_new(X) sock_new(X)		/* Wrapper to avoid name collision with OpenSSL */

int sk_open(sock *, struct birdloop *);		/* Open socket */
void sk_reloop(sock *, struct birdloop *);	/* Move socket to another loop. Both loops must be locked. */
static inline void sk_close(sock *s) { rfree(&s->r); }	/* Explicitly close socket */

int sk_rx_ready(sock *s);
bool sk_tx_pending(sock *s);
int sk_send(sock *, uint len);		/* Send data, <0=err, >0=ok, 0=sleep */
int sk_send_to(sock *, uint len, ip_addr to, uint port); /* sk_send to given destination */
void sk_reallocate(sock *);		/* Free and allocate tbuf & rbuf */
void sk_pause_rx(struct birdloop *loop, sock *s);
void sk_resume_rx(struct birdloop *loop, sock *s, int (*hook)(sock *, uint));
void sk_set_rbsize(sock *s, uint val);	/* Resize RX buffer */
void sk_set_tbsize(sock *s, uint val);	/* Resize TX buffer, keeping content */
void sk_set_tbuf(sock *s, void *tbuf);	/* Switch TX buffer, NULL-> return to internal */
void sk_dump_all(struct dump_request *);
void sk_dump_ao_all(struct dump_request *);

int sk_is_ipv4(sock *s);		/* True if socket is IPv4 */
int sk_is_ipv6(sock *s);		/* True if socket is IPv6 */

static inline int sk_tx_buffer_empty(sock *sk)
{ return sk->tbuf == sk->tpos; }

int sk_setup_multicast(sock *s);	/* Prepare UDP or IP socket for multicasting */
int sk_join_group(sock *s, ip_addr maddr);	/* Join multicast group on sk iface */
int sk_leave_group(sock *s, ip_addr maddr);	/* Leave multicast group on sk iface */
int sk_setup_broadcast(sock *s);
int sk_set_ttl(sock *s, int ttl);	/* Set transmit TTL for given socket */
int sk_set_min_ttl(sock *s, int ttl);	/* Set minimal accepted TTL for given socket */
int sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, int pxlen, struct iface *ifa, const char *passwd, int setkey);

bool tcp_ao_alg_known(int algorithm);
int sk_get_ao_info(sock *s, struct ao_info *val);
int sk_get_active_ao_keys(sock *s, int *current_key, int *rnext_key);
int sk_add_ao_key(sock *s, ip_addr prefix, int pxlen, struct iface *ifa, const struct ao_key *key, bool current, bool rnext);
int sk_delete_ao_key(sock *s, ip_addr prefix, int pxlen, struct iface *ifa, const struct ao_key *key, const struct ao_key *current, const struct ao_key *rnext);
int sk_set_rnext_ao_key(sock *s, const struct ao_key *key);
int sk_check_ao_keys(sock *s, const struct ao_key **keys, int num, const char *name);
void sk_dump_ao_info(sock *s, struct dump_request *dreq);
void sk_dump_ao_keys(sock *s, struct dump_request *dreq);

int sk_set_ipv6_checksum(sock *s, int offset);
int sk_set_icmp6_filter(sock *s, int p1, int p2);
void sk_log_error(sock *s, const char *p);

byte * sk_rx_buffer(sock *s, int *len);	/* Temporary */
sock *sk_next(sock *s);

extern int sk_priority_control;		/* Suggested priority for control traffic, should be sysdep define */


/* Socket flags */

#define SKF_V6ONLY	0x02	/* Use IPV6_V6ONLY socket option */
#define SKF_LADDR_RX	0x04	/* Report local address for RX packets */
#define SKF_TTL_RX	0x08	/* Report TTL / Hop Limit for RX packets */
#define SKF_BIND	0x10	/* Bind datagram socket to given source address */
#define SKF_HIGH_PORT	0x20	/* Choose port from high range if possible */
#define SKF_FREEBIND	0x40	/* Allow socket to bind to a nonlocal address */
#define SKF_CONNECT	0x80	/* Connect datagram socket to given dst address/port */

#define SKF_TRUNCATED	0x200	/* Received packet was truncated, set by IO layer */
#define SKF_HDRINCL	0x400	/* Used internally */
#define SKF_PKTINFO	0x800	/* Used internally */

#define SKF_UDP6_NO_CSUM_RX	0x1000	/* Accept zero checksums for received UDPv6 packets */

/*
 *	Socket types		     SA SP DA DP IF  TTL SendTo	(?=may, -=must not, *=must)
 */

#define SK_TCP_PASSIVE	0	   /* ?  *  -  -  -  ?   -	*/
#define SK_TCP_ACTIVE	1          /* ?  ?  *  *  -  ?   -	*/
#define SK_TCP		2
#define SK_UDP		3          /* ?  ?  ?  ?  ?  ?   ?	*/
#define SK_IP		5          /* ?  -  ?  *  ?  ?   ?	*/
#define SK_MAGIC	7	   /* Internal use by sysdep code */
#define SK_UNIX_PASSIVE	8
#define SK_UNIX		9
#define SK_SSH_ACTIVE	10         /* -  -  *  *  -  ?   -	DA = host */
#define SK_SSH		11

/*
 *	Socket subtypes
 */

#define SK_IPV4		1
#define SK_IPV6		2

/*
 * For TCP/IP sockets, Address family (IPv4 or IPv6) can be specified either
 * explicitly (SK_IPV4 or SK_IPV6) or implicitly (based on saddr, daddr). But
 * these specifications must be consistent.
 *
 * For SK_UDP or SK_IP sockets setting DA/DP allows to use sk_send(), otherwise
 * sk_send_to() must be used.
 *
 * For SK_IP sockets setting DP specifies protocol number, which is used for
 * both receiving and sending.
 *
 * For multicast on SK_UDP or SK_IP sockets set IF and TTL, call
 * sk_setup_multicast() to enable multicast on that socket, and then use
 * sk_join_group() and sk_leave_group() to manage a set of received multicast
 * groups.
 *
 * For datagram (SK_UDP, SK_IP) sockets, there are two ways to handle source
 * address. The socket could be bound to it using bind() syscall, but that also
 * forbids the reception of multicast packets, or the address could be set on
 * per-packet basis using platform dependent options (but these are not
 * available in some corner cases). The first way is used when SKF_BIND is
 * specified, the second way is used otherwise.
 */

#endif