version 1.7.3.0
[socat.git] / xio.h
bloba5b6fe4adde4ca05914c5a1cfb334af6442c3f99
1 /* source: xio.h */
2 /* Copyright Gerhard Rieger */
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 O_ACCMODE /* 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_READLINE 0x5000 /* ... */
49 #define XIOREAD_OPENSSL 0x6000 /* SSL_read() */
50 #define XIODATA_WRITEMASK 0x0f00 /* mask for basic r/w method */
51 #define XIOWRITE_STREAM 0x0100 /* write() (default) */
52 #define XIOWRITE_SENDTO 0x0200 /* sendto() */
53 #define XIOWRITE_PIPE 0x0300 /* write() to alternate (pipe) Fd */
54 #define XIOWRITE_2PIPE 0x0400 /* write() to alternate (2pipe) Fd */
55 #define XIOWRITE_READLINE 0x0500 /* check for prompt */
56 #define XIOWRITE_OPENSSL 0x0600 /* SSL_write() */
57 /* modifiers to XIODATA_READ_RECV */
58 #define XIOREAD_RECV_CHECKPORT 0x0001 /* recv, check peer port */
59 #define XIOREAD_RECV_CHECKADDR 0x0002 /* recv, check peer address */
60 #define XIOREAD_RECV_CHECKRANGE 0x0004 /* recv, check if peer addr in range */
61 #define XIOREAD_RECV_ONESHOT 0x0008 /* give EOF after first packet */
62 #define XIOREAD_RECV_SKIPIP 0x0010 /* recv, skip IPv4 header */
63 #define XIOREAD_RECV_FROM 0x0020 /* remember peer for replying */
65 /* combinations */
66 #define XIODATA_MASK (XIODATA_READMASK|XIODATA_WRITEMASK)
67 #define XIODATA_STREAM (XIOREAD_STREAM|XIOWRITE_STREAM)
68 #define XIODATA_RECVFROM (XIOREAD_RECV|XIOWRITE_SENDTO|XIOREAD_RECV_CHECKPORT|XIOREAD_RECV_CHECKADDR|XIOREAD_RECV_FROM)
69 #define XIODATA_RECVFROM_SKIPIP (XIODATA_RECVFROM|XIOREAD_RECV_SKIPIP)
70 #define XIODATA_RECVFROM_ONE (XIODATA_RECVFROM|XIOREAD_RECV_ONESHOT)
71 #define XIODATA_RECVFROM_SKIPIP_ONE (XIODATA_RECVFROM_SKIPIP|XIOREAD_RECV_ONESHOT)
72 #define XIODATA_RECV (XIOREAD_RECV|XIOWRITE_SENDTO|XIOREAD_RECV_CHECKRANGE)
73 #define XIODATA_RECV_SKIPIP (XIODATA_RECV|XIOREAD_RECV_SKIPIP)
74 #define XIODATA_PIPE (XIOREAD_STREAM|XIOWRITE_PIPE)
75 #define XIODATA_2PIPE (XIOREAD_STREAM|XIOWRITE_2PIPE)
76 #define XIODATA_PTY (XIOREAD_PTY|XIOWRITE_STREAM)
77 #define XIODATA_READLINE (XIOREAD_READLINE|XIOWRITE_STREAM)
78 #define XIODATA_OPENSSL (XIOREAD_OPENSSL|XIOWRITE_OPENSSL)
81 /* these are the values allowed for the "enum xiotag tag" flag of the "struct
82 single" and "union bipipe" (xiofile_t) structures. */
83 enum xiotag {
84 XIO_TAG_INVALID, /* the record is not in use */
85 XIO_TAG_RDONLY, /* this is a single read-only stream */
86 XIO_TAG_WRONLY, /* this is a single write-only stream */
87 XIO_TAG_RDWR, /* this is a single read-write stream */
88 XIO_TAG_DUAL /* this is a dual stream, consisting of two single
89 streams */
90 } ;
92 /* global XIO options/parameters */
93 typedef struct {
94 bool strictopts;
95 const char *pipesep;
96 const char *paramsep;
97 const char *optionsep;
98 char ip4portsep;
99 char ip6portsep; /* do not change, might be hardcoded somewhere! */
100 char logopt; /* 'm' means "switch to syslog when entering daemon mode" */
101 const char *syslogfac; /* syslog facility (only with mixed mode) */
102 char default_ip; /* default prot.fam for IP based listen ('4' or '6') */
103 char preferred_ip; /* preferred prot.fam. for name resolution ('0' for
104 unspecified, '4', or '6') */
105 } xioopts_t;
107 /* pack the description of a lock file */
108 typedef struct {
109 const char *lockfile; /* name of lockfile; NULL if no locking */
110 bool waitlock; /* dont't exit when already locked */
111 struct timespec intervall; /* polling intervall */
112 } xiolock_t;
114 extern xioopts_t xioopts;
116 #define MAXARGV 8
118 /* a non-dual file descriptor */
119 typedef struct single {
120 enum xiotag tag; /* see enum xiotag */
121 const struct addrdesc *addr;
122 int flags;
123 /* until here, keep consistent with bipipe.common !!! */
124 #if WITH_RETRY
125 unsigned int retry; /* retry opening this many times */
126 bool forever; /* retry opening forever */
127 struct timespec intervall; /* wait so long between retries */
128 #endif /* WITH_RETRY */
129 bool ignoreeof; /* option ignoreeof; do not pass eof condition to app*/
130 int eof; /* 1..exec'd child has died, but no explicit eof
131 occurred
132 2..fd0 has reached EOF (definitely; never with
133 ignoreeof! */
134 size_t wsize; /* write always this size; 0..all available */
135 size_t readbytes; /* read only so many bytes; 0...unlimited */
136 size_t actbytes; /* so many bytes still to be read (when readbytes!=0)*/
137 xiolock_t lock; /* parameters of lockfile */
138 bool havelock; /* we are happy owner of the above lock */
139 bool cool_write; /* downlevel EPIPE, ECONNRESET to notice */
140 /* until here, keep consistent with bipipe.dual ! */
141 int argc; /* number of fields in argv */
142 const char *argv[MAXARGV]; /* address keyword, required args */
143 struct opt *opts; /* the options of this address */
144 int lineterm; /* 0..dont touch; 1..CR; 2..CRNL on extern data */
145 int fd;
146 bool opt_unlink_close; /* option unlink_close */
147 char *unlink_close; /* name of a symlink or unix socket to be removed */
148 int dtype;
149 enum {
150 XIOSHUT_UNSPEC, /* standard (address dependent) behaviour */
151 XIOSHUT_NONE, /* do nothing on shutdown */
152 XIOSHUT_CLOSE, /* close the FD */
153 XIOSHUT_DOWN, /* shutdown() */
154 XIOSHUT_NULL /* send an empty packet (dgram socket) */
155 } howtoshut;
156 enum {
157 END_UNSPEC, /* after init, when no end-close... option */
158 END_NONE, /* no action */
159 END_CLOSE, /* close() */
160 END_SHUTDOWN, /* shutdown() */
161 END_KILL, /* has subprocess */
162 END_CLOSE_KILL, /* first close fd, then kill subprocess */
163 END_SHUTDOWN_KILL /* first shutdown fd, then kill subprocess */
164 } howtoend;
165 #if _WITH_SOCKET
166 union sockaddr_union peersa;
167 socklen_t salen;
168 #endif /* _WITH_SOCKET */
169 #if WITH_TERMIOS
170 bool ttyvalid; /* the following struct is valid */
171 struct termios savetty; /* save orig tty settings for later restore */
172 #endif /* WITH_TERMIOS */
173 int (*sigchild)(struct single *); /* callback after sigchild */
174 pid_t ppid; /* parent pid, only if we send it signals */
175 int escape; /* escape character; -1 for no escape */
176 bool actescape; /* escape character found in input data */
177 union {
178 struct {
179 int fdout; /* use fd for output */
180 } bipipe;
181 #if _WITH_SOCKET
182 struct {
183 struct timeval connect_timeout; /* how long to hang in connect() */
184 union sockaddr_union la; /* local socket address */
185 bool null_eof; /* with dgram: empty packet means EOF */
186 bool dorange;
187 struct xiorange range; /* restrictions for peer address */
188 #if _WITH_IP4 || _WITH_IP6
189 struct {
190 unsigned int res_opts[2]; /* bits to be set in _res.options are
191 at [0], bits to be cleared are at [1] */
192 bool dosourceport;
193 uint16_t sourceport; /* host byte order */
194 bool lowport;
195 #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
196 bool dolibwrap;
197 char *libwrapname;
198 char *tcpwrap_etc;
199 char *hosts_allow_table;
200 char *hosts_deny_table;
201 #endif
202 } ip;
203 #endif /* _WITH_IP4 || _WITH_IP6 */
204 #if WITH_UNIX
205 struct {
206 bool tight;
207 } un;
208 #endif /* WITH_UNIX */
209 } socket;
210 #endif /* _WITH_SOCKET */
211 struct {
212 pid_t pid; /* child PID, with EXEC: */
213 int fdout; /* use fd for output if two pipes */
214 } exec;
215 #if WITH_READLINE
216 struct {
217 char *history_file;
218 char *prompt; /* static prompt, passed to readline() */
219 size_t dynbytes; /* length of buffer for dynamic prompt */
220 char *dynprompt; /* the dynamic prompt */
221 char *dynend; /* current end of dynamic prompt */
222 #if HAVE_REGEX_H
223 bool hasnoecho; /* following regex is set */
224 regex_t noecho; /* if it matches the prompt, input is silent */
225 #endif
226 } readline;
227 #endif /* WITH_READLINE */
228 #if WITH_OPENSSL
229 struct {
230 struct timeval connect_timeout; /* how long to hang in connect() */
231 SSL *ssl;
232 SSL_CTX* ctx;
233 } openssl;
234 #endif /* WITH_OPENSSL */
235 #if WITH_TUN
236 struct {
237 short iff_opts[2]; /* ifr flags, using OFUNC_OFFSET_MASKS */
238 } tun;
239 #endif /* WITH_TUN */
240 } para;
241 } xiosingle_t;
243 /* rw: 0..read, 1..write, 2..r/w */
244 /* when implementing a new address type take care of following topics:
245 . be aware that xioopen_single is used for O_RDONLY, O_WRONLY, and O_RDWR data
246 . which options are allowed (option groups)
247 . implement application of all these options
248 . set FD_CLOEXEC on new file descriptors BEFORE the cloexec option might be
249 applied
253 typedef union bipipe {
254 enum xiotag tag;
255 struct {
256 enum xiotag tag;
257 const struct addrdesc *addr;
258 int flags;
259 } common;
260 struct single stream;
261 struct {
262 enum xiotag tag;
263 const struct addrdesc *addr;
264 int flags; /* compatible to fcntl(.., F_GETFL, ..) */
265 #if WITH_RETRY
266 unsigned retry; /* retry opening this many times */
267 bool forever; /* retry opening forever */
268 struct timespec intervall; /* wait so long between retries */
269 #endif /* WITH_RETRY */
270 bool ignoreeof;
271 int eof; /* fd0 has reached EOF */
272 size_t wsize; /* write always this size; 0..all available */
273 size_t readbytes; /* read only so many bytes; 0...unlimited */
274 size_t actbytes; /* so many bytes still to be read */
275 xiolock_t lock; /* parameters of lockfile */
276 bool havelock; /* we are happy owner of the above lock */
277 xiosingle_t *stream[2]; /* input stream, output stream */
278 } dual;
279 } xiofile_t;
282 struct addrdesc {
283 const char *defname; /* main (canonical) name of address */
284 int directions; /* 1..read, 2..write, 3..both */
285 int (*func)(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, unsigned groups,
286 int arg1, int arg2, int arg3);
287 unsigned groups;
288 int arg1;
289 int arg2;
290 int arg3;
291 #if WITH_HELP
292 const char *syntax;
293 #endif
296 #define XIO_WRITABLE(s) (((s)->common.flags+1)&2)
297 #define XIO_READABLE(s) (((s)->common.flags+1)&1)
298 #define XIO_RDSTREAM(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]:&(s)->stream)
299 #define XIO_WRSTREAM(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[1]:&(s)->stream)
300 #define XIO_GETRDFD(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]->fd:(s)->stream.fd)
301 #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)
302 #define XIO_EOF(s) (XIO_RDSTREAM(s)->eof && !XIO_RDSTREAM(s)->ignoreeof)
304 typedef unsigned long flags_t;
306 union integral {
307 int u_bool;
308 uint8_t u_byte;
309 gid_t u_gidt;
310 int u_int;
311 long u_long;
312 #if HAVE_TYPE_LONGLONG
313 long long u_longlong;
314 #endif
315 double u_double;
316 mode_t u_modet;
317 short u_short;
318 size_t u_sizet;
319 char *u_string;
320 uid_t u_uidt;
321 unsigned int u_uint;
322 unsigned long u_ulong;
323 unsigned short u_ushort;
324 uint16_t u_2bytes;
325 void *u_ptr;
326 flags_t u_flag;
327 struct {
328 uint8_t *b_data;
329 size_t b_len;
330 } u_bin;
331 struct timeval u_timeval;
332 #if HAVE_STRUCT_LINGER
333 struct linger u_linger;
334 #endif /* HAVE_STRUCT_LINGER */
335 #if HAVE_STRUCT_TIMESPEC
336 struct timespec u_timespec;
337 #endif /* HAVE_STRUCT_TIMESPEC */
338 #if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN
339 struct {
340 char *multiaddr;
341 char *param2; /* address, interface */
342 #if HAVE_STRUCT_IP_MREQN
343 char ifindex[IF_NAMESIZE+1];
344 #endif
345 } u_ip_mreq;
346 #endif
347 #if WITH_IP4
348 struct in_addr u_ip4addr;
349 #endif
352 /* some aliases */
354 #if HAVE_BASIC_OFF_T==3
355 # define u_off u_int
356 #elif HAVE_BASIC_OFF_T==5
357 # define u_off u_long
358 #elif HAVE_BASIC_OFF_T==7
359 # define u_off u_longlong
360 #else
361 # error "unexpected size of off_t, please report this as bug"
362 #endif
364 #if defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T
365 # if HAVE_BASIC_OFF64_T==5
366 # define u_off64 u_long
367 # elif HAVE_BASIC_OFF64_T==7
368 # define u_off64 u_longlong
369 # else
370 # error "unexpected size of off64_t, please report this as bug"
371 # endif
372 #endif /* defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T */
375 /* this handles option instances, for communication between subroutines */
376 struct opt {
377 const struct optdesc *desc;
378 union integral value;
379 union integral value2;
380 union integral value3;
383 extern const char *PIPESEP;
384 extern xiofile_t *sock[XIO_MAXSOCK];
386 extern int num_child;
388 /* return values of xioopensingle */
389 #define STAT_OK 0
390 #define STAT_WARNING 1
391 #define STAT_EXIT 2
392 #define STAT_NOACTION 3 /* by retropt_* when option not applied */
393 #define STAT_RETRYNOW -1 /* only after timeouts useful ? */
394 #define STAT_RETRYLATER -2 /* address cannot be opened, but user might
395 change something in the filesystem etc. to
396 make this process succeed later. */
397 #define STAT_NORETRY -3 /* address syntax error, not implemented etc;
398 not even by external changes correctable */
400 extern int xioinitialize(void);
401 extern int xioinitialize2(void);
402 extern pid_t xio_fork(bool subchild, int level);
403 extern int xio_forked_inchild(void);
404 extern int xiosetopt(char what, const char *arg);
405 extern int xioinqopt(char what, char *arg, size_t n);
406 extern xiofile_t *xioopen(const char *args, int flags);
407 extern int xioopensingle(char *addr, struct single *xfd, int xioflags);
408 extern int xioopenhelp(FILE *of, int level);
410 /* must be outside function for use by childdied handler */
411 extern xiofile_t *sock1, *sock2;
412 #define NUMUNKNOWN 4
413 extern pid_t diedunknown[NUMUNKNOWN]; /* child died before it is registered */
414 #define diedunknown1 (diedunknown[0])
415 #define diedunknown2 (diedunknown[1])
416 #define diedunknown3 (diedunknown[2])
417 #define diedunknown4 (diedunknown[3])
419 extern int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *));
420 extern int xiosetchilddied(void);
421 extern int xio_opt_signal(pid_t pid, int signum);
422 extern void childdied(int signum);
424 extern ssize_t xioread(xiofile_t *sock1, void *buff, size_t bufsiz);
425 extern ssize_t xiopending(xiofile_t *sock1);
426 extern ssize_t xiowrite(xiofile_t *sock1, const void *buff, size_t bufsiz);
427 extern int xioshutdown(xiofile_t *sock, int how);
429 extern int xioclose(xiofile_t *sock);
430 extern void xioexit(void);
432 extern int (*xiohook_newchild)(void); /* xio calls this function from a new child process */
434 #endif /* !defined(__xio_h_included) */