Version 1.8.0.0
[socat.git] / xio.h
blob072431434f18157cb1e3887592dc01e943b5935e
1 /* source: xio.h */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 #ifndef __xio_h_included
6 #define __xio_h_included 1
8 #if 1 /*!*/
9 #include "mytypes.h"
10 #include "sysutils.h"
11 #endif
13 #define XIO_MAXSOCK 2
15 /* Linux 2.2.10 */
16 #define HAVE_STRUCT_LINGER 1
18 #define LINETERM_RAW 0
19 #define LINETERM_CR 1
20 #define LINETERM_CRNL 2
22 struct addrdesc;
23 struct opt;
25 /* the flags argument of xioopen */
26 #define XIO_RDONLY O_RDONLY /* asserted to be 0 */
27 #define XIO_WRONLY O_WRONLY /* asserted to be 1 */
28 #define XIO_RDWR O_RDWR /* asserted to be 2 */
29 #define XIO_ACCMODE (XIO_RDONLY|XIO_WRONLY|XIO_RDWR) /* must be 3 */
30 #define XIO_MAYFORK 4 /* address is allowed to fork the program (fork) */
31 #define XIO_MAYCHILD 8 /* address is allowed to fork off a child (exec)*/
32 #define XIO_MAYEXEC 16 /* address is allowed to exec a prog (exec+nofork) */
33 #define XIO_MAYCONVERT 32 /* address is allowed to perform modifications on the
34 stream data, e.g. SSL, REALDINE; CRLF */
36 /* the status flags of xiofile_t */
37 #define XIO_DOESFORK XIO_MAYFORK
38 #define XIO_DOESCHILD XIO_MAYCHILD
39 #define XIO_DOESEXEC XIO_MAYEXEC
40 #define XIO_DOESCONVERT XIO_MAYCONVERT
43 /* methods for reading and writing, and for related checks */
44 #define XIODATA_READMASK 0xf000 /* mask for basic r/w method */
45 #define XIOREAD_STREAM 0x1000 /* read() (default) */
46 #define XIOREAD_RECV 0x2000 /* recvfrom() */
47 #define XIOREAD_PTY 0x4000 /* handle EIO */
48 #define XIOREAD_POSIXMQ 0x5000 /* POSIX MQ */
49 #define XIOREAD_READLINE 0x6000 /* ... */
50 #define XIOREAD_OPENSSL 0x7000 /* SSL_read() */
51 #define XIODATA_WRITEMASK 0x0f00 /* mask for basic r/w method */
52 #define XIOWRITE_STREAM 0x0100 /* write() (default) */
53 #define XIOWRITE_SENDTO 0x0200 /* sendto() */
54 #define XIOWRITE_PIPE 0x0300 /* write() to alternate (pipe) Fd */
55 #define XIOWRITE_2PIPE 0x0400 /* write() to alternate (2pipe) Fd */
56 #define XIOWRITE_POSIXMQ 0x0500 /* POSIX MQ */
57 #define XIOWRITE_READLINE 0x0600 /* check for prompt */
58 #define XIOWRITE_OPENSSL 0x0700 /* SSL_write() */
59 /* modifiers to XIODATA_READ_RECV */
60 #define XIOREAD_RECV_CHECKPORT 0x0001 /* recv, check peer port */
61 #define XIOREAD_RECV_CHECKADDR 0x0002 /* recv, check peer address */
62 #define XIOREAD_RECV_CHECKRANGE 0x0004 /* recv, check if peer addr in range */
63 #define XIOREAD_RECV_ONESHOT 0x0008 /* give EOF after first packet */
64 #define XIOREAD_RECV_SKIPIP 0x0010 /* recv, skip IPv4 header */
65 #define XIOREAD_RECV_FROM 0x0020 /* remember peer for replying */
66 #define XIOREAD_RECV_NOCHECK 0x0040 /* do not check peer */
68 /* combinations */
69 #define XIODATA_MASK (XIODATA_READMASK|XIODATA_WRITEMASK)
70 #define XIODATA_STREAM (XIOREAD_STREAM|XIOWRITE_STREAM)
71 #define XIODATA_RECVFROM (XIOREAD_RECV|XIOWRITE_SENDTO|XIOREAD_RECV_CHECKPORT|XIOREAD_RECV_CHECKADDR|XIOREAD_RECV_FROM)
72 #define XIODATA_RECVFROM_SKIPIP (XIODATA_RECVFROM|XIOREAD_RECV_SKIPIP)
73 #define XIODATA_RECVFROM_ONE (XIODATA_RECVFROM|XIOREAD_RECV_ONESHOT)
74 #define XIODATA_RECVFROM_SKIPIP_ONE (XIODATA_RECVFROM_SKIPIP|XIOREAD_RECV_ONESHOT)
75 #define XIODATA_RECV (XIOREAD_RECV|XIOWRITE_SENDTO|XIOREAD_RECV_CHECKRANGE)
76 #define XIODATA_RECV_SKIPIP (XIODATA_RECV|XIOREAD_RECV_SKIPIP)
77 #define XIODATA_PIPE (XIOREAD_STREAM|XIOWRITE_PIPE)
78 #define XIODATA_2PIPE (XIOREAD_STREAM|XIOWRITE_2PIPE)
79 #define XIODATA_POSIXMQ (XIOREAD_POSIXMQ|XIOWRITE_POSIXMQ)
80 #define XIODATA_PTY (XIOREAD_PTY|XIOWRITE_STREAM)
81 #define XIODATA_READLINE (XIOREAD_READLINE|XIOWRITE_STREAM)
82 #define XIODATA_OPENSSL (XIOREAD_OPENSSL|XIOWRITE_OPENSSL)
85 /* these are the values allowed for the "enum xiotag tag" flag of the "struct
86 single" and "union bipipe" (xiofile_t) structures. */
87 enum xiotag {
88 XIO_TAG_INVALID, /* the record is not in use */
89 XIO_TAG_RDONLY, /* this is a single read-only stream */
90 XIO_TAG_WRONLY, /* this is a single write-only stream */
91 XIO_TAG_RDWR, /* this is a single read-write stream */
92 XIO_TAG_DUAL, /* this is a dual stream, consisting of two single
93 streams */
94 XIO_TAG_CLOSED=8, /* close, additional bit */
95 } ;
97 /* Keep condition consistent with xioopts.h:GROUP_*! */
98 #if WITH_POSIXMQ || WITH_SCTP || WITH_DCCP || WITH_UDPLITE
99 typedef uint64_t groups_t;
100 #define F_groups_t F_uint64_x
101 #else
102 typedef uint32_t groups_t;
103 #define F_groups_t F_uint32_x
104 #endif
106 /* global XIO options/parameters */
107 typedef struct xioparms {
108 bool strictopts;
109 const char *pipesep;
110 const char *paramsep;
111 const char *optionsep;
112 char ip4portsep;
113 char ip6portsep; /* do not change, might be hardcoded somewhere! */
114 char logopt; /* 'm' means "switch to syslog when entering daemon mode" */
115 const char *syslogfac; /* syslog facility (only with mixed mode) */
116 char default_ip; /* default prot.fam for IP based listen ('4' '6' or '\0') */
117 char preferred_ip; /* preferred prot.fam. for name resolution ('0' for
118 unspecified, '4', or '6') */
119 bool experimental; /* enable some features */
120 const char *sniffleft_name; /* file name with -r */
121 const char *sniffright_name; /* file name with -R */
122 size_t bufsiz;
123 } xioparms_t;
125 /* pack the description of a lock file */
126 typedef struct {
127 const char *lockfile; /* name of lockfile; NULL if no locking */
128 bool waitlock; /* dont't exit when already locked */
129 struct timespec intervall; /* polling intervall */
130 } xiolock_t;
132 extern xioparms_t xioparms;
134 #define MAXARGV 8
136 #if _WITH_IP4 || _WITH_IP6
137 #if WITH_RESOLVE && HAVE_RESOLV_H
138 struct para_ip_res {
139 unsigned int opts[2]; /* bits to be set in _res.options are in [0],
140 bits to be cleared are in [1] */
141 #if HAVE_RES_RETRANS
142 int retrans;
143 #endif
144 #if HAVE_RES_RETRY
145 int retry;
146 #endif
147 #if HAVE_RES_NSADDR_LIST
148 # undef nsaddr /* resolv.h might define this, breaks debugger */
149 struct sockaddr_in nsaddr;
150 #endif
152 #endif /* WITH_RESOLVE && HAVE_RESOLV_H */
154 struct para_ip {
155 int ai_flags[2]; /* flags for getaddrinfo() ai_flags (set/unset) */
156 #if WITH_RESOLVE && HAVE_RESOLV_H
157 struct para_ip_res res;
158 #endif
159 bool dosourceport; /* check the source port of incoming connection or packets */
160 uint16_t sourceport; /* host byte order */
161 bool lowport;
162 #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
163 bool dolibwrap;
164 char *libwrapname;
165 char *tcpwrap_etc;
166 char *hosts_allow_table;
167 char *hosts_deny_table;
168 #endif
170 #endif /* _WITH_IP4 || _WITH_IP6 */
172 /* a non-dual file descriptor */
173 typedef struct single {
174 enum xiotag tag; /* see enum xiotag */
175 const struct addrdesc *addr;
176 int flags;
177 /* until here, keep consistent with bipipe.common !!! */
178 #if WITH_RETRY
179 unsigned int retry; /* retry opening this many times */
180 bool forever; /* retry opening forever */
181 struct timespec intervall; /* wait so long between retries */
182 #endif /* WITH_RETRY */
183 bool ignoreeof; /* option ignoreeof; do not pass eof condition to app*/
184 int eof; /* 1..exec'd child has died, but no explicit eof
185 occurred
186 2..fd0 has reached EOF, but check for ignoreeof
187 3..fd0 has reached EOF (definitely; never with
188 ignoreeof! */
189 size_t wsize; /* write always this size; 0..all available */
190 size_t readbytes; /* read only so many bytes; 0...unlimited */
191 size_t actbytes; /* so many bytes still to be read (when readbytes!=0)*/
192 xiolock_t lock; /* parameters of lockfile */
193 bool havelock; /* we are happy owner of the above lock */
194 int triggerfd; /* in child process close this FD to notify parent */
195 bool cool_write; /* downlevel EPIPE, ECONNRESET to notice */
196 /* until here, keep consistent with bipipe.dual ! */
197 int argc; /* number of fields in argv */
198 const char *argv[MAXARGV]; /* address keyword, required args */
199 struct opt *opts; /* the options of this address */
200 int lineterm; /* 0..dont touch; 1..CR; 2..CRNL on extern data */
201 int fd;
202 bool opt_unlink_close; /* option unlink_close */
203 char *unlink_close; /* name of a symlink or unix socket to be removed */
204 int dtype;
205 enum {
206 XIOSHUT_UNSPEC, /* standard (address dependent) behaviour */
207 XIOSHUT_NONE, /* do nothing on shutdown */
208 XIOSHUT_CLOSE, /* close the FD */
209 XIOSHUT_DOWN, /* shutdown() */
210 XIOSHUT_NULL /* send an empty packet (dgram socket) */
211 } howtoshut;
212 enum {
213 END_UNSPEC, /* after init, when no end-close... option */
214 END_NONE, /* no action */
215 END_CLOSE, /* close() */
216 END_SHUTDOWN, /* shutdown() */
217 END_KILL, /* has subprocess */
218 END_CLOSE_KILL, /* first close fd, then kill subprocess */
219 END_SHUTDOWN_KILL,/* first shutdown fd, then kill subprocess */
220 END_INTERFACE /* restore interface flags, then close fd */
221 } howtoend;
222 #if _WITH_SOCKET
223 union sockaddr_union peersa;
224 socklen_t salen;
225 #endif /* _WITH_SOCKET */
226 #if WITH_TERMIOS
227 bool ttyvalid; /* the following struct is valid */
228 struct termios savetty; /* save orig tty settings for later restore */
229 #endif /* WITH_TERMIOS */
230 int (*sigchild)(struct single *); /* callback after sigchild */
231 int escape; /* escape character; -1 for no escape */
232 bool actescape; /* escape character found in input data */
233 int shutup; /* children-shutup option */
234 union {
235 struct {
236 int fdout; /* use fd for output */
237 int socktype;
238 } bipipe;
239 #if _WITH_SOCKET
240 struct {
241 /* keep a consistent copy in openssl part !!! */
242 struct timeval connect_timeout; /* how long to hang in connect() */
243 #if WITH_LISTEN
244 struct timeval accept_timeout; /* how long to wait for incoming connection */
245 #endif
246 union sockaddr_union la; /* local socket address */
247 bool null_eof; /* with dgram: empty packet means EOF */
248 bool dorange;
249 struct xiorange range; /* restrictions for peer address */
250 #if _WITH_IP4 || _WITH_IP6
251 struct para_ip ip;
252 #endif /* _WITH_IP4 || _WITH_IP6 */
253 /* Copy in openssl part up to here ! */
254 #if HAVE_STRUCT_TPACKET_AUXDATA
255 struct {
256 int packet_auxdata;
257 } ancill_flag;
258 #endif
259 #if HAVE_STRUCT_TPACKET_AUXDATA
260 struct tpacket_auxdata ancill_data_packet_auxdata;
261 bool retrieve_vlan;
262 #endif
263 #if WITH_UNIX
264 struct {
265 bool tight;
266 } un;
267 #endif /* WITH_UNIX */
268 } socket;
269 #endif /* _WITH_SOCKET */
270 #if WITH_POSIXMQ
271 struct {
272 const char *name;
273 unsigned int prio; /* POSIX message queue */
274 } posixmq;
275 #endif /* WITH_POSIXMQ */
276 struct {
277 int fdout; /* use fd for output if two pipes */
278 pid_t pid; /* child PID, with EXEC: */
279 struct timeval sitout_eio;
280 } exec;
281 #if WITH_READLINE
282 struct {
283 char *history_file;
284 char *prompt; /* static prompt, passed to readline() */
285 size_t dynbytes; /* length of buffer for dynamic prompt */
286 char *dynprompt; /* the dynamic prompt */
287 char *dynend; /* current end of dynamic prompt */
288 #if HAVE_REGEX_H
289 bool hasnoecho; /* following regex is set */
290 regex_t noecho; /* if it matches the prompt, input is silent */
291 #endif
292 } readline;
293 #endif /* WITH_READLINE */
294 #if WITH_OPENSSL
295 struct {
296 /* copy of the para.socket structure without un !!! */
297 struct timeval connect_timeout; /* how long to hang in connect() */
298 #if WITH_LISTEN
299 struct timeval accept_timeout; /* how long to wait for incoming connection */
300 #endif
301 union sockaddr_union la; /* local socket address */
302 bool null_eof; /* with dgram: empty packet means EOF */
303 bool dorange;
304 struct xiorange range; /* restrictions for peer address */
305 #if _WITH_IP4 || _WITH_IP6
306 struct para_ip ip;
307 #endif /* _WITH_IP4 || _WITH_IP6 */
308 /* end of the para.socket structure copy */
309 SSL_CTX* ctx; /* for freeing on close */
310 SSL *ssl;
311 #if HAVE_SSL_CTX_set_min_proto_version || defined(SSL_CTX_set_min_proto_version)
312 char *min_proto_version;
313 #endif
314 #if HAVE_SSL_CTX_set_max_proto_version || defined(SSL_CTX_set_max_proto_version)
315 char *max_proto_version;
316 #endif
317 } openssl;
318 #endif /* WITH_OPENSSL */
319 #if _WITH_INTERFACE
320 struct {
321 char name[IFNAMSIZ]; /* name of interface */
322 short save_iff; /* for restoring old settings on exit */
323 short iff_opts[2]; /* ifr flags, using OFUNC_OFFSET_MASKS */
324 } interface;
325 #endif /* _WITH_INTERFACE */
326 } para;
327 #if WITH_STATS
328 unsigned long long blocks_read;
329 unsigned long long bytes_read;
330 unsigned long long blocks_written;
331 unsigned long long bytes_written;
332 #endif /* WITH_STATS */
333 } xiosingle_t;
335 /* rw: 0..read, 1..write, 2..r/w */
336 /* when implementing a new address type take care of following topics:
337 . be aware that xioopen_single is used for O_RDONLY, O_WRONLY, and O_RDWR data
338 . which options are allowed (option groups)
339 . implement application of all these options
340 . set FD_CLOEXEC on new file descriptors BEFORE the cloexec option might be
341 applied
345 typedef union bipipe {
346 enum xiotag tag;
347 struct {
348 enum xiotag tag;
349 const struct addrdesc *addr;
350 int flags;
351 /* until here, keep consistent with struct single, and with .dual */
352 } common; /* "bipipe.common" */
353 struct single stream;
354 struct {
355 enum xiotag tag;
356 const struct addrdesc *addr;
357 int flags; /* compatible to fcntl(.., F_GETFL, ..) */
358 #if WITH_RETRY
359 unsigned retry; /* retry opening this many times */
360 bool forever; /* retry opening forever */
361 struct timespec intervall; /* wait so long between retries */
362 #endif /* WITH_RETRY */
363 bool ignoreeof;
364 int eof; /* fd0 has reached EOF */
365 size_t wsize; /* write always this size; 0..all available */
366 size_t readbytes; /* read only so many bytes; 0...unlimited */
367 size_t actbytes; /* so many bytes still to be read */
368 xiolock_t lock; /* parameters of lockfile */
369 bool havelock; /* we are happy owner of the above lock */
370 int triggerfd; /* close this FD in child process to notify parent */
371 bool cool_write; /* downlevel EPIPE, ECONNRESET to notice */
372 /* until here, keep consistent with struct single ! */
373 struct single *stream[2]; /* input stream, output stream */
374 } dual;
375 } xiofile_t;
378 struct addrdesc {
379 const char *defname; /* main (canonical) name of address */
380 int directions; /* 1..read, 2..write, 3..both */
381 int (*func)(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, const struct addrdesc *addrdesc);
382 groups_t groups;
383 int arg1;
384 int arg2;
385 int arg3;
386 #if WITH_HELP
387 const char *syntax;
388 #endif
391 #define XIO_WRITABLE(s) (((s)->common.flags+1)&2)
392 #define XIO_READABLE(s) (((s)->common.flags+1)&1)
393 #define XIO_RDSTREAM(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]:&(s)->stream)
394 #define XIO_WRSTREAM(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[1]:&(s)->stream)
395 #define XIO_GETRDFD(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]->fd:(s)->stream.fd)
396 #define XIO_GETWRFD(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[1]->fd:(((s)->stream.dtype&XIODATA_WRITEMASK)==XIOWRITE_2PIPE)?(s)->stream.para.exec.fdout:(((s)->stream.dtype&XIODATA_WRITEMASK)==XIOWRITE_PIPE)?(s)->stream.para.bipipe.fdout:(s)->stream.fd)
397 #define XIO_EOF(s) (XIO_RDSTREAM(s)->eof && !XIO_RDSTREAM(s)->ignoreeof)
399 typedef unsigned long flags_t;
401 union integral {
402 bool u_bool;
403 uint8_t u_byte;
404 gid_t u_gidt;
405 int u_int;
406 long u_long;
407 #if HAVE_TYPE_LONGLONG
408 long long u_longlong;
409 #endif
410 double u_double;
411 mode_t u_modet;
412 short u_short;
413 size_t u_sizet;
414 char *u_string;
415 uid_t u_uidt;
416 unsigned int u_uint;
417 unsigned long u_ulong;
418 unsigned short u_ushort;
419 uint16_t u_2bytes;
420 void *u_ptr;
421 flags_t u_flag;
422 struct {
423 uint8_t *b_data;
424 size_t b_len;
425 } u_bin;
426 struct timeval u_timeval;
427 #if HAVE_STRUCT_LINGER
428 struct linger u_linger;
429 #endif /* HAVE_STRUCT_LINGER */
430 #if HAVE_STRUCT_TIMESPEC
431 struct timespec u_timespec;
432 #endif /* HAVE_STRUCT_TIMESPEC */
433 #if WITH_IP4
434 struct in_addr u_ip4addr;
435 struct sockaddr_in u_ip4sock;
436 #endif
439 /* some aliases */
441 #if HAVE_BASIC_OFF_T==3
442 # define u_off u_int
443 #elif HAVE_BASIC_OFF_T==5
444 # define u_off u_long
445 #elif HAVE_BASIC_OFF_T==7
446 # define u_off u_longlong
447 #else
448 # error "unexpected size of off_t, please report this as bug"
449 #endif
451 #if defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T
452 # if HAVE_BASIC_OFF64_T==5
453 # define u_off64 u_long
454 # elif HAVE_BASIC_OFF64_T==7
455 # define u_off64 u_longlong
456 # else
457 # error "unexpected size of off64_t, please report this as bug"
458 # endif
459 #endif /* defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T */
462 /* this handles option instances, for communication between subroutines */
463 struct opt {
464 const struct optdesc *desc;
465 union integral value;
466 union integral value2;
467 union integral value3;
470 extern const char *PIPESEP;
471 extern xiofile_t *sock[XIO_MAXSOCK];
473 extern int num_child;
475 /* return values of xioopensingle */
476 #define STAT_OK 0
477 #define STAT_WARNING 1
478 #define STAT_EXIT 2
479 #define STAT_NOACTION 3 /* by retropt_* when option not applied */
480 #define STAT_RETRYNOW -1 /* only after timeouts useful ? */
481 #define STAT_RETRYLATER -2 /* address cannot be opened, but user might
482 change something in the filesystem etc. to
483 make this process succeed later. */
484 #define STAT_NORETRY -3 /* address syntax error, not implemented etc;
485 not even by external changes correctable */
487 extern int xioinitialize(void);
488 extern int xioinitialize2(void);
489 extern pid_t xio_fork(bool subchild, int level, int shutup);
490 extern int xio_forked_inchild(void);
491 extern int xiosetopt(char what, const char *arg);
492 extern int xioinqopt(char what, char *arg, size_t n);
493 extern xiofile_t *xioopen(const char *args, int flags);
494 extern int xioopensingle(char *addr, struct single *xfd, int xioflags);
495 extern int xioopenhelp(FILE *of, int level);
497 /* must be outside function for use by childdied handler */
498 extern xiofile_t *sock1, *sock2;
499 extern int sniffleft, sniffright;
501 #define NUMUNKNOWN 4
502 extern pid_t diedunknown[NUMUNKNOWN]; /* child died before it is registered */
503 #define diedunknown1 (diedunknown[0])
504 #define diedunknown2 (diedunknown[1])
505 #define diedunknown3 (diedunknown[2])
506 #define diedunknown4 (diedunknown[3])
507 extern int statunknown[NUMUNKNOWN]; /* exit state of unknown dead child */
508 extern int engine_result; /* here signal handler overrides OK */
510 extern int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *));
511 extern int xiosetchilddied(void);
512 extern int xio_opt_signal(pid_t pid, int signum);
513 extern void childdied(int signum);
515 extern ssize_t xioread(xiofile_t *sock1, void *buff, size_t bufsiz);
516 extern ssize_t xiopending(xiofile_t *sock1);
517 extern ssize_t xiowrite(xiofile_t *sock1, const void *buff, size_t bufsiz);
518 extern int xioshutdown(xiofile_t *sock, int how);
520 extern int xioclose(xiofile_t *sock);
521 extern void xioexit(void);
523 extern int (*xiohook_newchild)(void); /* xio calls this function from a new child process */
525 #endif /* !defined(__xio_h_included) */