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 */ 4 5 #ifndef __xio_h_included 6 #define __xio_h_included 1 7 8 #if 1 /*!*/ 9 #include "mytypes.h" 10 #include "sysutils.h" 11 #endif 12 13 #define XIO_MAXSOCK 2 14 15 /* Linux 2.2.10 */ 16 #define HAVE_STRUCT_LINGER 1 17 18 #define LINETERM_RAW 0 19 #define LINETERM_CR 1 20 #define LINETERM_CRNL 2 21 22 struct addrdesc; 23 struct opt; 24 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 */ 35 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 41 42 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 */ 64 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) 79 80 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 } ; 91 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; 106 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; 113 114 extern xioopts_t xioopts; 115 116 #define MAXARGV 8 117 118 #if _WITH_IP4 || _WITH_IP6 119 struct para_ip { 120 unsigned int res_opts[2]; /* bits to be set in _res.options are 121 at [0], bits to be cleared are at [1] */ 122 bool dosourceport; /* check the source port of incoming connection or packets */ 123 uint16_t sourceport; /* host byte order */ 124 bool lowport; 125 #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP 126 bool dolibwrap; 127 char *libwrapname; 128 char *tcpwrap_etc; 129 char *hosts_allow_table; 130 char *hosts_deny_table; 131 #endif 132 } ; 133 #endif /* _WITH_IP4 || _WITH_IP6 */ 134 135 /* a non-dual file descriptor */ 136 typedef struct single { 137 enum xiotag tag; /* see enum xiotag */ 138 const struct addrdesc *addr; 139 int flags; 140 /* until here, keep consistent with bipipe.common !!! */ 141 #if WITH_RETRY 142 unsigned int retry; /* retry opening this many times */ 143 bool forever; /* retry opening forever */ 144 struct timespec intervall; /* wait so long between retries */ 145 #endif /* WITH_RETRY */ 146 bool ignoreeof; /* option ignoreeof; do not pass eof condition to app*/ 147 int eof; /* 1..exec'd child has died, but no explicit eof 148 occurred 149 2..fd0 has reached EOF, but check for ignoreeof 150 3..fd0 has reached EOF (definitely; never with 151 ignoreeof! */ 152 size_t wsize; /* write always this size; 0..all available */ 153 size_t readbytes; /* read only so many bytes; 0...unlimited */ 154 size_t actbytes; /* so many bytes still to be read (when readbytes!=0)*/ 155 xiolock_t lock; /* parameters of lockfile */ 156 bool havelock; /* we are happy owner of the above lock */ 157 bool cool_write; /* downlevel EPIPE, ECONNRESET to notice */ 158 /* until here, keep consistent with bipipe.dual ! */ 159 int argc; /* number of fields in argv */ 160 const char *argv[MAXARGV]; /* address keyword, required args */ 161 struct opt *opts; /* the options of this address */ 162 int lineterm; /* 0..dont touch; 1..CR; 2..CRNL on extern data */ 163 int fd; 164 bool opt_unlink_close; /* option unlink_close */ 165 char *unlink_close; /* name of a symlink or unix socket to be removed */ 166 int dtype; 167 enum { 168 XIOSHUT_UNSPEC, /* standard (address dependent) behaviour */ 169 XIOSHUT_NONE, /* do nothing on shutdown */ 170 XIOSHUT_CLOSE, /* close the FD */ 171 XIOSHUT_DOWN, /* shutdown() */ 172 XIOSHUT_NULL /* send an empty packet (dgram socket) */ 173 } howtoshut; 174 enum { 175 END_UNSPEC, /* after init, when no end-close... option */ 176 END_NONE, /* no action */ 177 END_CLOSE, /* close() */ 178 END_SHUTDOWN, /* shutdown() */ 179 END_KILL, /* has subprocess */ 180 END_CLOSE_KILL, /* first close fd, then kill subprocess */ 181 END_SHUTDOWN_KILL /* first shutdown fd, then kill subprocess */ 182 } howtoend; 183 #if _WITH_SOCKET 184 union sockaddr_union peersa; 185 socklen_t salen; 186 #endif /* _WITH_SOCKET */ 187 #if WITH_TERMIOS 188 bool ttyvalid; /* the following struct is valid */ 189 struct termios savetty; /* save orig tty settings for later restore */ 190 #endif /* WITH_TERMIOS */ 191 int (*sigchild)(struct single *); /* callback after sigchild */ 192 pid_t ppid; /* parent pid, only if we send it signals */ 193 int escape; /* escape character; -1 for no escape */ 194 bool actescape; /* escape character found in input data */ 195 union { 196 struct { 197 int fdout; /* use fd for output */ 198 } bipipe; 199 #if _WITH_SOCKET 200 struct { 201 /* keep a consistent copy in openssl part !!! */ 202 struct timeval connect_timeout; /* how long to hang in connect() */ 203 #if WITH_LISTEN 204 struct timeval accept_timeout; /* how long to wait for incoming connection */ 205 #endif 206 union sockaddr_union la; /* local socket address */ 207 bool null_eof; /* with dgram: empty packet means EOF */ 208 bool dorange; 209 struct xiorange range; /* restrictions for peer address */ 210 #if _WITH_IP4 || _WITH_IP6 211 struct para_ip ip; 212 #endif /* _WITH_IP4 || _WITH_IP6 */ 213 /* up to here, keep consistent copy in openssl part !!! */ 214 #if WITH_UNIX 215 struct { 216 bool tight; 217 } un; 218 #endif /* WITH_UNIX */ 219 } socket; 220 #endif /* _WITH_SOCKET */ 221 struct { 222 pid_t pid; /* child PID, with EXEC: */ 223 int fdout; /* use fd for output if two pipes */ 224 } exec; 225 #if WITH_READLINE 226 struct { 227 char *history_file; 228 char *prompt; /* static prompt, passed to readline() */ 229 size_t dynbytes; /* length of buffer for dynamic prompt */ 230 char *dynprompt; /* the dynamic prompt */ 231 char *dynend; /* current end of dynamic prompt */ 232 #if HAVE_REGEX_H 233 bool hasnoecho; /* following regex is set */ 234 regex_t noecho; /* if it matches the prompt, input is silent */ 235 #endif 236 } readline; 237 #endif /* WITH_READLINE */ 238 #if WITH_OPENSSL 239 struct { 240 /* copy of the para.socket structure without un !!! */ 241 struct timeval connect_timeout; /* how long to hang in connect() */ 242 #if WITH_LISTEN 243 struct timeval accept_timeout; /* how long to wait for incoming connection */ 244 #endif 245 union sockaddr_union la; /* local socket address */ 246 bool null_eof; /* with dgram: empty packet means EOF */ 247 bool dorange; 248 struct xiorange range; /* restrictions for peer address */ 249 #if _WITH_IP4 || _WITH_IP6 250 struct para_ip ip; 251 #endif /* _WITH_IP4 || _WITH_IP6 */ 252 /* end of the para.socket structure copy */ 253 SSL_CTX* ctx; /* for freeing on close */ 254 SSL *ssl; 255 #if HAVE_SSL_CTX_set_min_proto_version || defined(SSL_CTX_set_min_proto_version) 256 char *min_proto_version; 257 #endif 258 #if HAVE_SSL_CTX_set_max_proto_version || defined(SSL_CTX_set_max_proto_version) 259 char *max_proto_version; 260 #endif 261 } openssl; 262 #endif /* WITH_OPENSSL */ 263 #if WITH_TUN 264 struct { 265 short iff_opts[2]; /* ifr flags, using OFUNC_OFFSET_MASKS */ 266 } tun; 267 #endif /* WITH_TUN */ 268 } para; 269 } xiosingle_t; 270 271 /* rw: 0..read, 1..write, 2..r/w */ 272 /* when implementing a new address type take care of following topics: 273 . be aware that xioopen_single is used for O_RDONLY, O_WRONLY, and O_RDWR data 274 . which options are allowed (option groups) 275 . implement application of all these options 276 . set FD_CLOEXEC on new file descriptors BEFORE the cloexec option might be 277 applied 278 . 279 */ 280 281 typedef union bipipe { 282 enum xiotag tag; 283 struct { 284 enum xiotag tag; 285 const struct addrdesc *addr; 286 int flags; 287 } common; 288 struct single stream; 289 struct { 290 enum xiotag tag; 291 const struct addrdesc *addr; 292 int flags; /* compatible to fcntl(.., F_GETFL, ..) */ 293 #if WITH_RETRY 294 unsigned retry; /* retry opening this many times */ 295 bool forever; /* retry opening forever */ 296 struct timespec intervall; /* wait so long between retries */ 297 #endif /* WITH_RETRY */ 298 bool ignoreeof; 299 int eof; /* fd0 has reached EOF */ 300 size_t wsize; /* write always this size; 0..all available */ 301 size_t readbytes; /* read only so many bytes; 0...unlimited */ 302 size_t actbytes; /* so many bytes still to be read */ 303 xiolock_t lock; /* parameters of lockfile */ 304 bool havelock; /* we are happy owner of the above lock */ 305 xiosingle_t *stream[2]; /* input stream, output stream */ 306 } dual; 307 } xiofile_t; 308 309 310 struct addrdesc { 311 const char *defname; /* main (canonical) name of address */ 312 int directions; /* 1..read, 2..write, 3..both */ 313 int (*func)(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, unsigned groups, 314 int arg1, int arg2, int arg3); 315 unsigned groups; 316 int arg1; 317 int arg2; 318 int arg3; 319 #if WITH_HELP 320 const char *syntax; 321 #endif 322 } ; 323 324 #define XIO_WRITABLE(s) (((s)->common.flags+1)&2) 325 #define XIO_READABLE(s) (((s)->common.flags+1)&1) 326 #define XIO_RDSTREAM(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]:&(s)->stream) 327 #define XIO_WRSTREAM(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[1]:&(s)->stream) 328 #define XIO_GETRDFD(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]->fd:(s)->stream.fd) 329 #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) 330 #define XIO_EOF(s) (XIO_RDSTREAM(s)->eof && !XIO_RDSTREAM(s)->ignoreeof) 331 332 typedef unsigned long flags_t; 333 334 union integral { 335 bool u_bool; 336 uint8_t u_byte; 337 gid_t u_gidt; 338 int u_int; 339 long u_long; 340 #if HAVE_TYPE_LONGLONG 341 long long u_longlong; 342 #endif 343 double u_double; 344 mode_t u_modet; 345 short u_short; 346 size_t u_sizet; 347 char *u_string; 348 uid_t u_uidt; 349 unsigned int u_uint; 350 unsigned long u_ulong; 351 unsigned short u_ushort; 352 uint16_t u_2bytes; 353 void *u_ptr; 354 flags_t u_flag; 355 struct { 356 uint8_t *b_data; 357 size_t b_len; 358 } u_bin; 359 struct timeval u_timeval; 360 #if HAVE_STRUCT_LINGER 361 struct linger u_linger; 362 #endif /* HAVE_STRUCT_LINGER */ 363 #if HAVE_STRUCT_TIMESPEC 364 struct timespec u_timespec; 365 #endif /* HAVE_STRUCT_TIMESPEC */ 366 #if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN 367 struct { 368 char *multiaddr; 369 char *param2; /* address, interface */ 370 #if HAVE_STRUCT_IP_MREQN 371 char ifindex[IF_NAMESIZE+1]; 372 #endif 373 } u_ip_mreq; 374 #endif 375 #if HAVE_STRUCT_IP_MREQ_SOURCE 376 struct { 377 char *mcaddr; 378 char *ifaddr; /* address, interface */ 379 char *srcaddr; /* source address */ 380 } u_ip_mreq_source; 381 #endif 382 #if WITH_IP4 383 struct in_addr u_ip4addr; 384 #endif 385 } ; 386 387 /* some aliases */ 388 389 #if HAVE_BASIC_OFF_T==3 390 # define u_off u_int 391 #elif HAVE_BASIC_OFF_T==5 392 # define u_off u_long 393 #elif HAVE_BASIC_OFF_T==7 394 # define u_off u_longlong 395 #else 396 # error "unexpected size of off_t, please report this as bug" 397 #endif 398 399 #if defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T 400 # if HAVE_BASIC_OFF64_T==5 401 # define u_off64 u_long 402 # elif HAVE_BASIC_OFF64_T==7 403 # define u_off64 u_longlong 404 # else 405 # error "unexpected size of off64_t, please report this as bug" 406 # endif 407 #endif /* defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T */ 408 409 410 /* this handles option instances, for communication between subroutines */ 411 struct opt { 412 const struct optdesc *desc; 413 union integral value; 414 union integral value2; 415 union integral value3; 416 } ; 417 418 extern const char *PIPESEP; 419 extern xiofile_t *sock[XIO_MAXSOCK]; 420 421 extern int num_child; 422 423 /* return values of xioopensingle */ 424 #define STAT_OK 0 425 #define STAT_WARNING 1 426 #define STAT_EXIT 2 427 #define STAT_NOACTION 3 /* by retropt_* when option not applied */ 428 #define STAT_RETRYNOW -1 /* only after timeouts useful ? */ 429 #define STAT_RETRYLATER -2 /* address cannot be opened, but user might 430 change something in the filesystem etc. to 431 make this process succeed later. */ 432 #define STAT_NORETRY -3 /* address syntax error, not implemented etc; 433 not even by external changes correctable */ 434 435 extern int xioinitialize(void); 436 extern int xioinitialize2(void); 437 extern pid_t xio_fork(bool subchild, int level); 438 extern int xio_forked_inchild(void); 439 extern int xiosetopt(char what, const char *arg); 440 extern int xioinqopt(char what, char *arg, size_t n); 441 extern xiofile_t *xioopen(const char *args, int flags); 442 extern int xioopensingle(char *addr, struct single *xfd, int xioflags); 443 extern int xioopenhelp(FILE *of, int level); 444 445 /* must be outside function for use by childdied handler */ 446 extern xiofile_t *sock1, *sock2; 447 #define NUMUNKNOWN 4 448 extern pid_t diedunknown[NUMUNKNOWN]; /* child died before it is registered */ 449 #define diedunknown1 (diedunknown[0]) 450 #define diedunknown2 (diedunknown[1]) 451 #define diedunknown3 (diedunknown[2]) 452 #define diedunknown4 (diedunknown[3]) 453 extern int statunknown[NUMUNKNOWN]; /* exit state of unknown dead child */ 454 455 extern int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *)); 456 extern int xiosetchilddied(void); 457 extern int xio_opt_signal(pid_t pid, int signum); 458 extern void childdied(int signum); 459 460 extern ssize_t xioread(xiofile_t *sock1, void *buff, size_t bufsiz); 461 extern ssize_t xiopending(xiofile_t *sock1); 462 extern ssize_t xiowrite(xiofile_t *sock1, const void *buff, size_t bufsiz); 463 extern int xioshutdown(xiofile_t *sock, int how); 464 465 extern int xioclose(xiofile_t *sock); 466 extern void xioexit(void); 467 468 extern int (*xiohook_newchild)(void); /* xio calls this function from a new child process */ 469 470 #endif /* !defined(__xio_h_included) */ 471