3 * Main header file for port forwarder
5 * (c) 1999 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the `fwd' port forwarder.
12 * `fwd' is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * `fwd' is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with `fwd'; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 /*----- Header files ------------------------------------------------------*/
36 /* --- Configuration --- */
62 #include <sys/types.h>
68 #include <sys/socket.h>
70 #include <netinet/in.h>
71 #include <arpa/inet.h>
81 #include <mLib/alloc.h>
82 #include <mLib/bres.h>
83 #include <mLib/conn.h>
84 #include <mLib/darray.h>
85 #include <mLib/dstr.h>
87 #include <mLib/fdflags.h>
88 #include <mLib/fdpass.h>
89 #include <mLib/ident.h>
90 #include <mLib/macros.h>
91 #include <mLib/mdup.h>
92 #include <mLib/mdwopt.h>
93 #include <mLib/quis.h>
94 #include <mLib/report.h>
96 #include <mLib/selbuf.h>
100 #include <mLib/sym.h>
103 /*----- Other subtleties --------------------------------------------------*/
105 #if defined(HAVE_DECL_ENVIRON) && !HAVE_DECL_ENVIRON
106 extern char **environ
;
109 /*----- Resource limit names ----------------------------------------------*/
111 #if defined(RLIMIT_OFILE) && !defined(RLIMIT_NOFILE)
112 # define RLIMIT_NOFILE RLIMIT_OFILE
116 ;;; The resource-limit name table is very boring to type and less fun to
117 ;;; maintain. To make life less awful, put the names in this list and
118 ;;; evaluate the code to get Emacs to regenerate it.
120 (let ((limits '(as core cpu data fsize locks memlock msgqueue
121 nice nofile nproc rss rtprio sigpending stack
126 (search-forward (concat "***" "BEGIN rlimitlist" "***"))
127 (beginning-of-line 2)
128 (delete-region (point)
130 (search-forward "***END***")
133 (let ((avail (make-marker))
134 (list (make-marker)))
135 (set-marker avail (point))
136 (insert "#define RLIMITS(_)")
137 (set-marker list (point))
138 (dolist (limit (sort (copy-list limits) #'string<))
139 (let* ((name (symbol-name limit))
140 (constant (concat "RLIMIT_" (upcase name)))
141 (have (concat "HAVE_" constant "_P")))
143 (insert-before-markers (format (concat "#ifdef %s\n"
150 (insert-before-markers
151 (format " \\\n MAYBE_ITEM(_, %s, (%s, %s))"
152 have name constant))))
157 /***BEGIN rlimitlist***/
159 # define HAVE_RLIMIT_AS_P t
161 # define HAVE_RLIMIT_AS_P nil
164 # define HAVE_RLIMIT_CORE_P t
166 # define HAVE_RLIMIT_CORE_P nil
169 # define HAVE_RLIMIT_CPU_P t
171 # define HAVE_RLIMIT_CPU_P nil
174 # define HAVE_RLIMIT_DATA_P t
176 # define HAVE_RLIMIT_DATA_P nil
179 # define HAVE_RLIMIT_FSIZE_P t
181 # define HAVE_RLIMIT_FSIZE_P nil
184 # define HAVE_RLIMIT_LOCKS_P t
186 # define HAVE_RLIMIT_LOCKS_P nil
188 #ifdef RLIMIT_MEMLOCK
189 # define HAVE_RLIMIT_MEMLOCK_P t
191 # define HAVE_RLIMIT_MEMLOCK_P nil
193 #ifdef RLIMIT_MSGQUEUE
194 # define HAVE_RLIMIT_MSGQUEUE_P t
196 # define HAVE_RLIMIT_MSGQUEUE_P nil
199 # define HAVE_RLIMIT_NICE_P t
201 # define HAVE_RLIMIT_NICE_P nil
204 # define HAVE_RLIMIT_NOFILE_P t
206 # define HAVE_RLIMIT_NOFILE_P nil
209 # define HAVE_RLIMIT_NPROC_P t
211 # define HAVE_RLIMIT_NPROC_P nil
214 # define HAVE_RLIMIT_RSS_P t
216 # define HAVE_RLIMIT_RSS_P nil
219 # define HAVE_RLIMIT_RTPRIO_P t
221 # define HAVE_RLIMIT_RTPRIO_P nil
223 #ifdef RLIMIT_SIGPENDING
224 # define HAVE_RLIMIT_SIGPENDING_P t
226 # define HAVE_RLIMIT_SIGPENDING_P nil
229 # define HAVE_RLIMIT_STACK_P t
231 # define HAVE_RLIMIT_STACK_P nil
234 # define HAVE_RLIMIT_VMEM_P t
236 # define HAVE_RLIMIT_VMEM_P nil
239 MAYBE_ITEM(_, HAVE_RLIMIT_AS_P, (as, RLIMIT_AS)) \
240 MAYBE_ITEM(_, HAVE_RLIMIT_CORE_P, (core, RLIMIT_CORE)) \
241 MAYBE_ITEM(_, HAVE_RLIMIT_CPU_P, (cpu, RLIMIT_CPU)) \
242 MAYBE_ITEM(_, HAVE_RLIMIT_DATA_P, (data, RLIMIT_DATA)) \
243 MAYBE_ITEM(_, HAVE_RLIMIT_FSIZE_P, (fsize, RLIMIT_FSIZE)) \
244 MAYBE_ITEM(_, HAVE_RLIMIT_LOCKS_P, (locks, RLIMIT_LOCKS)) \
245 MAYBE_ITEM(_, HAVE_RLIMIT_MEMLOCK_P, (memlock, RLIMIT_MEMLOCK)) \
246 MAYBE_ITEM(_, HAVE_RLIMIT_MSGQUEUE_P, (msgqueue, RLIMIT_MSGQUEUE)) \
247 MAYBE_ITEM(_, HAVE_RLIMIT_NICE_P, (nice, RLIMIT_NICE)) \
248 MAYBE_ITEM(_, HAVE_RLIMIT_NOFILE_P, (nofile, RLIMIT_NOFILE)) \
249 MAYBE_ITEM(_, HAVE_RLIMIT_NPROC_P, (nproc, RLIMIT_NPROC)) \
250 MAYBE_ITEM(_, HAVE_RLIMIT_RSS_P, (rss, RLIMIT_RSS)) \
251 MAYBE_ITEM(_, HAVE_RLIMIT_RTPRIO_P, (rtprio, RLIMIT_RTPRIO)) \
252 MAYBE_ITEM(_, HAVE_RLIMIT_SIGPENDING_P, (sigpending, RLIMIT_SIGPENDING)) \
253 MAYBE_ITEM(_, HAVE_RLIMIT_STACK_P, (stack, RLIMIT_STACK)) \
254 MAYBE_ITEM(_, HAVE_RLIMIT_VMEM_P, (vmem, RLIMIT_VMEM))
257 /* --- The unpleasant conditional-output machinery --- */
259 #define MAYBE_ITEM(_, emitp, args) GLUE(MAYBE_ITEM_, emitp)(_, args)
260 #define MAYBE_ITEM_t(_, args) _ args
261 #define MAYBE_ITEM_nil(_, args)
263 /*----- Main program ------------------------------------------------------*/
265 /* --- The global select state --- */
267 extern sel_state
*sel
;
269 /* --- Global state flags --- */
271 extern unsigned flags
;
277 /* --- Help text --- */
279 extern const char grammar_text
[];
280 extern const char option_text
[];
282 /* --- Generally useful magic constants --- */
284 #define NOW ((time_t)-1)
286 /* --- @fw_log@ --- *
288 * Arguments: @time_t t@ = when the connection occurred or (@NOW@)
289 * @const char *fmt@ = format string to fill in
290 * @...@ = other arguments
294 * Use: Logs a connection.
297 extern void PRINTF_LIKE(2, 3)
298 fw_log(time_t /*t*/, const char */
*fmt*/
, ...);
300 /* --- @fw_inc@, @fw_dec@ --- *
306 * Use: Increments or decrements the active thing count. `fwd' won't
307 * quit while there are active things.
310 extern void fw_inc(void);
311 extern void fw_dec(void);
313 /*----- Channel management ------------------------------------------------*/
315 /* --- Magic numbers --- */
317 #define CHAN_BUFSZ 4096
319 /* --- Channel structure --- */
321 typedef struct chan
{
322 unsigned base
, len
; /* Base and length of data */
323 unsigned f
; /* Various interesting flags */
324 void (*func
)(void */
*p*/
); /* Function to call on closure */
325 int err
; /* What's wrong with the channel */
326 void *p
; /* Argument to pass function */
327 sel_file r
, w
; /* Reader and writer selectors */
328 char buf
[CHAN_BUFSZ
]; /* The actual data buffer */
331 #define CHANF_CLOSE 1u /* Close channel when buffer empty */
332 #define CHANF_READY 2u /* The channel destination exists */
334 /* --- @chan_close@ --- *
336 * Arguments: @chan *c@ = pointer to channel
340 * Use: Closes down a channel prematurely.
343 extern void chan_close(chan */
*c*/
);
345 /* --- @chan_dest@ --- *
347 * Arguments: @chan *c@ = pointer to channel
348 * @int fd@ = destination file descriptor for channel
352 * Use: Sets the channel's destination so it knows where to put
356 extern void chan_dest(chan */
*c*/
, int /*fd*/);
358 /* --- @chan_open@ --- *
360 * Arguments: @chan *c@ = pointer to channel to open
361 * @int from, to@ = source and destination file descriptors
362 * @void (*func)(void *p)@ = function to call on closure
363 * @void *p@ = argument to pass to function
367 * Use: Opens a channel. Data is copied from the source to the
368 * destination. The @to@ argument may be @-1@ if the file
369 * descriptor isn't known yet.
372 extern void chan_open(chan */
*c*/
, int /*from*/, int /*to*/,
373 void (*/
*func*/
)(void */
*p*/
), void */
*p*/
);
375 /*----- Character scanners ------------------------------------------------*/
377 /* --- A low-level scanner source --- */
379 typedef struct scansrc
{
380 struct scansrc
*next
; /* Next one in the list */
381 struct scansrc_ops
*ops
; /* Pointer to operations table */
382 char *src
; /* Name of this source */
383 int line
; /* Current line number */
384 dstr pushback
; /* Pushback characters */
385 char *tok
; /* Token pushback */
386 unsigned t
; /* Token type pushback */
389 /* --- Scanner source operations --- */
391 typedef struct scansrc_ops
{
392 int (*scan
)(scansrc */
*ss*/
); /* Read another character */
393 void (*destroy
)(scansrc */
*ss*/
); /* Destroy an unwanted source */
396 /* --- A character scanner --- */
398 typedef struct scanner
{
399 scansrc
*head
, **tail
; /* Scanner list head and tail */
400 int t
; /* Token type */
401 dstr d
; /* Current token value */
402 const char *wbegin
, *wcont
; /* Parsing exception strings */
405 /* --- @scan_file@ --- *
407 * Arguments: @FILE *fp@ = pointer to file descriptor
408 * @const char *name@ = pointer to source file name
409 * @unsigned f@ = flags
411 * Returns: A scanner source.
413 * Use: Creates a new scanner source for reading from a file.
416 #define SCF_NOCLOSE 1u /* Don't close @fp@ when finished */
418 extern scansrc
*scan_file(FILE */
*fp*/
, const char */
*name*/
,
421 /* --- @scan_argv@ --- *
423 * Arguments: @char **av@ = pointer to argument array (null terminated)
425 * Returns: A scanner source.
427 * Use: Creates a new scanner source for reading from an @argv@
431 extern scansrc
*scan_argv(char **/
*av*/
);
435 * Arguments: @scanner *sc@ = pointer to main scanner context
437 * Returns: Character read, or end-of-file.
439 * Use: Scans a character from a source of characters.
442 extern int scan(scanner */
*sc*/
);
444 /* --- @unscan@ --- *
446 * Arguments: @scanner *sc@ = pointer to main scanner context
447 * @int ch@ = character to unscan
451 * Use: Scans a character from a source of characters.
454 extern void unscan(scanner */
*sc*/
, int /*ch*/);
456 /* --- @scan_push@ --- *
458 * Arguments: @scanner *sc@ = pointer to main scanner context
459 * @scansrc *ss@ = souorce to push
463 * Use: Pushes a scanner source onto the front of the queue.
466 extern void scan_push(scanner */
*sc*/
, scansrc */
*ss*/
);
468 /* --- @scan_add@ --- *
470 * Arguments: @scanner *sc@ = pointer to main scanner context
471 * @scansrc *ss@ = souorce to push
475 * Use: Adds a scanner source onto the end of the queue.
478 extern void scan_add(scanner */
*sc*/
, scansrc */
*ss*/
);
480 /* --- @scan_create@ --- *
482 * Arguments: @scanner *sc@ = scanner context to initialize
486 * Use: Initializes a scanner block ready for use.
489 extern void scan_create(scanner */
*sc*/
);
491 /* --- @scan_destroy@ --- *
493 * Arguments: @scanner *sc@ = pointer to scanner context
497 * Use: Destroys a scanner and all the sources attached to it.
500 extern void scan_destroy(scanner */
*sc*/
);
502 /*----- Configuration parsing ---------------------------------------------*/
504 /* --- Magical constants --- */
506 #define CTOK_EOF (-1)
507 #define CTOK_WORD 256
509 /* --- @conf_undelim@ --- *
511 * Arguments: @scanner *sc@ = pointer to scanner definition
512 * @const char *d, *dd@ = pointer to characters to escape
516 * Use: Modifies the tokenizer. Characters in the first list will
517 * always be considered to begin a word. Characters in the
518 * second list will always be allowed to continue a word.
521 extern void conf_undelim(scanner */
*sc*/
,
522 const char */
*d*/
, const char */
*dd*/
);
526 * Arguments: @scanner *sc@ = pointer to scanner definition
528 * Returns: Type of token scanned.
530 * Use: Reads the next token from the character scanner.
533 extern int token(scanner */
*sc*/
);
537 * Arguments: @scanner *sc@ = pointer to scanner definition
538 * @const char *msg@ = message skeleton string
539 * @...@ = extra arguments for the skeleton
543 * Use: Reports an error at the current scanner location.
546 extern void PRINTF_LIKE(2, 3) NORETURN
547 error(scanner */
*sc*/
, const char */
*msg*/
, ...);
549 /* --- @pushback@ --- *
551 * Arguments: @scanner *sc@ = pointer to scanner definition
555 * Use: Pushes the current token back. This is normally a precursor
556 * to pushing a new scanner source.
559 extern void pushback(scanner */
*sc*/
);
561 /* --- @conf_enum@ --- *
563 * Arguments: @scanner *sc@ = pointer to a scanner object
564 * @const char *list@ = comma-separated things to allow
565 * @unsigned @f = flags for the search
566 * @const char *err@ = error message if not found
568 * Returns: Index into list, zero-based, or @-1@.
570 * Use: Checks whether the current token is a string which matches
571 * one of the comma-separated items given. The return value is
572 * the index (zero-based) of the matched string in the list.
574 * The flags control the behaviour if no exact match is found.
575 * If @ENUM_ABBREV@ is set, and the current token is a left
576 * substring of exactly one of the possibilities, then that one
577 * is chosen. If @ENUM_NONE@ is set, the value @-1@ is
578 * returned; otherwise an error is reported and the program is
582 #define ENUM_ABBREV 1u
585 extern int conf_enum(scanner */
*sc*/
, const char */
*list*/
,
586 unsigned /*flags*/, const char */
*err*/
);
588 /* --- @conf_prefix@ --- *
590 * Arguments: @scanner *sc@ = pointer to a scanner object
591 * @const char *p@ = pointer to prefix string to check
593 * Returns: Nonzero if the prefix matches.
595 * Use: If the current token is a word matching the given prefix
596 * string, then it and an optional `.' character are removed and
597 * a nonzero result is returned. Otherwise the current token is
598 * left as it is, and zero is returned.
600 * Typical options parsing code would remove an expected prefix,
601 * scan an option anyway (since qualifying prefixes are
602 * optional) and if a match is found, claim the option. If no
603 * match is found, and a prefix was stripped, then an error
604 * should be reported.
607 extern int conf_prefix(scanner */
*sc*/
, const char */
*p*/
);
609 /* --- @CONF_BEGIN@, @CONF_END@ --- *
611 * Arguments: @sc@ = scanner to read from
612 * @prefix@ = prefix to scan for
613 * @desc@ = description of what we're parsing
615 * Use: Bracket an options parsing routine. The current token is
616 * checked to see whether it matches the prefix. If so, it is
617 * removed and the following token examined. If that's a `.'
618 * then it's removed. If it's a `{' then the enclosed
619 * option-parsing code is executed in a loop until a matching
620 * '}' is found. If the options parser doesn't accept an
621 * option, the behaviour is dependent on whether a prefix was
622 * seen: if so, an error is reported; otherwse a zero return is
631 #define CONF_BEGIN(sc, prefix, desc) do { \
632 scanner *_conf_sc = (sc); \
633 const char *_conf_desc = (desc); \
634 int _conf_state = CS_PLAIN; \
636 /* --- Read the initial prefix --- */ \
638 if (_conf_sc->t == CTOK_WORD && \
639 strcmp(_conf_sc->d.buf, (prefix)) == 0) { \
641 _conf_state = CS_PREFIX; \
642 if (_conf_sc->t == '.') \
644 else if (_conf_sc->t == '{') { \
646 _conf_state = CS_BRACE; \
650 /* --- Ensure the next token is a word --- */ \
652 if (_conf_sc->t != CTOK_WORD) \
653 error(_conf_sc, "parse error, expected option keyword"); \
658 /* --- Reject an option --- * \
660 * We could get here as a result of an explicit @CONF_REJECT@ or \
661 * because the option wasn't accepted. \
666 if (_conf_state == CS_PLAIN) \
667 _conf_state = CS_UNKNOWN; \
669 error(_conf_sc, "unknown %s option `%s'", \
670 _conf_desc, _conf_sc->d.buf); \
673 /* --- Accept an option --- * \
675 * It's safe to drop through from above. Either an error will have \
676 * been reported, or the state is not @CS_BRACE@. \
680 if (_conf_state == CS_BRACE && _conf_sc->t == ';') \
682 } while (_conf_state == CS_BRACE && _conf_sc->t == CTOK_WORD); \
684 /* --- Check for a closing brace --- */ \
686 if (_conf_state == CS_BRACE) { \
687 if (_conf_sc->t == '}') \
690 error(_conf_sc, "parse error, expected `}'"); \
693 /* --- Return an appropriate value --- */ \
695 return (_conf_state != CS_UNKNOWN); \
698 /* --- @CONF_ACCEPT@, @CONF_REJECT@ --- *
702 * Use: Within an options parser (between @CONF_BEGIN@ and
703 * @CONF_END@), accept or reject an option.
706 #define CONF_ACCEPT goto _conf_accept
707 #define CONF_REJECT goto _conf_reject
709 /* --- @CONF_QUAL@ --- *
713 * Use: Evaluates to a nonzero value if the current option is
714 * qualified. This can be used to decide whether abbreviations
715 * for options should be accepted.
718 #define CONF_QUAL (_conf_state != CS_PLAIN)
720 /* --- @conf_name@ --- *
722 * Arguments: @scanner *sc@ = pointer to scanner
723 * @char delim@ = delimiter character to look for
724 * @dstr *d@ = pointer to dynamic string for output
728 * Use: Reads in a compound name consisting of words separated by
729 * delimiters. Leading and trailing delimiters are permitted,
730 * although they'll probably cause confusion if used. The name
731 * may be enclosed in square brackets if that helps at all.
733 * Examples of compound names are filenames (delimited by `/')
734 * and IP addresses (delimited by `.').
737 extern void conf_name(scanner */
*sc*/
, char /*delim*/, dstr */
*d*/
);
739 /* --- @conf_fname@ --- *
741 * Arguments: @scanner *sc@ = pointer to scanner
742 * @dstr *d@ = pointer to dynamic string for output
746 * Use: Reads a file name from the input and stores it in @d@.
749 extern void conf_fname(scanner */
*sc*/
, dstr */
*d*/
);
751 /*----- Reference-counted file descriptors --------------------------------*/
753 typedef struct reffd
{
756 void (*proc
)(void */
*p*/
);
760 /* --- @reffd_init@ --- *
762 * Arguments: @int fd@ = file descriptor
764 * Returns: Reference-counted file descriptor object.
766 * Use: Creates a refcounted file descriptor.
769 extern reffd
*reffd_init(int /*fd*/);
771 /* --- @reffd_handler@ --- *
773 * Arguments: @reffd *r@ = pointer to reference counted filehandle
774 * @void (*proc)(void *p)@ = procedure to call
779 * Use: Sets the reference counted file descriptor to call @proc@
780 * when it is no longer required.
783 extern void reffd_handler(reffd */
*r*/
, void (*/
*proc*/
)(void */
*p*/
),
786 /* --- @reffd_inc@ --- *
788 * Arguments: @reffd *r@ = pointer to reference counted filehandle
792 * Use: Increments the reference count for a file descriptor.
795 #define REFFD_INC(r) do { (r)->ref++; } while (0)
797 extern void reffd_inc(reffd */
*r*/
);
799 /* --- @reffd_dec@ --- *
801 * Arguments: @reffd *r@ = pointer to reference counted filehandle
805 * Use: Decrements the reference count for a file descriptor.
808 #define REFFD_DEC(r) do { \
811 if (_r->ref == 0) { \
819 extern void reffd_dec(reffd */
*r*/
);
821 /*----- Sources, targets and endpoints ------------------------------------*/
823 /* --- Basic endpoint structure --- */
825 typedef struct endpt
{
826 struct endpt_ops
*ops
; /* Pointer to operations table */
827 struct endpt
*other
; /* Pointer to sibling endpoint */
828 unsigned f
; /* Various flags */
829 struct tango
*t
; /* Private data structure */
830 reffd
*in
, *out
; /* File descriptors */
833 /* --- Endpoint flags --- */
835 #define EPF_PENDING 1u /* Endpoint creation in progress */
836 #define EPF_FILE 2u /* Endpoint smells like a file */
838 /* --- Endpoint operations table --- */
840 typedef struct endpt_ops
{
842 /* --- @attach@ --- *
844 * Arguments: @endpt *e@ = pointer to endpoint to be attached
845 * @reffd *in, *out@ = input and output file descriptors
849 * Use: Instructs a non-file endpoint to attach itself to a pair of
853 void (*attach
)(endpt */
*e*/
, reffd */
*in*/
, reffd */
*out*/
);
857 * Arguments: @endpt *e@ = pointer to endpoint in question
858 * @endpt *f@ = pointer to a file endpoint
862 * Use: Informs a non-file endpoint of a file endpoint which will
863 * want to be closed when it's finished with. At that time, the
864 * endpoint should arrange to have both itself and its partner
865 * closed. If no file is registered, the endpoint manager will
866 * close both endpoints itself.
869 void (*file
)(endpt */
*e*/
, endpt */
*f*/
);
871 /* --- @wclose@ --- *
873 * Arguments: @endpt *e@ = endpoint to be partially closed
877 * Use: Announces that the endpoint will not be written to any more.
880 void (*wclose
)(endpt */
*e*/
);
884 * Arguments: @endpt *e@ = endpoint to be closed
888 * Use: Completely closes an endpoint. The endpoint's data may be
889 * freed, although some endpoints may wish to delay freeing for
893 void (*close
)(endpt */
*e*/
);
897 /* --- A basic target object --- */
899 typedef struct target
{
900 struct target_ops
*ops
;
904 /* --- Forwarding target operations --- */
906 typedef struct target_ops
{
907 const char *name
; /* Name of this target */
909 /* --- @option@ --- *
911 * Arguments: @target *t@ = pointer to target object, or zero if global
912 * @scanner *sc@ = scanner to read from
914 * Returns: Nonzero to claim the option.
916 * Use: Handles an option string from the configuration file.
919 int (*option
)(target */
*t*/
, scanner */
*sc*/
);
923 * Arguments: @scanner *sc@ = pointer to scanner to read from
925 * Returns: Pointer to a target object to claim, null to reject.
927 * Use: Parses a target description from the configuration file.
928 * Only the socket target is allowed to omit the prefix on a
929 * target specification.
932 target
*(*read
)(scanner */
*sc*/
);
934 /* --- @confirm@ --- *
936 * Arguments: @target *t@ = pointer to target
940 * Use: Confirms configuration of a target.
943 void (*confirm
)(target */
*t*/
);
945 /* --- @create@ --- *
947 * Arguments: @target *t@ = pointer to target
948 * @const char *desc@ = description of connection
950 * Returns: Pointer to a created endpoint.
952 * Use: Generates a target endpoint for communication.
955 endpt
*(*create
)(target */
*t*/
, const char */
*desc*/
);
957 /* --- @destroy@ --- *
959 * Arguments: @target *t@ = pointer to target
963 * Use: Destroys a target.
966 void (*destroy
)(target */
*t*/
);
970 /* --- A basic source object --- */
972 typedef struct source
{
973 struct source
*next
, *prev
;
974 struct source_ops
*ops
;
978 /* --- Forwarding source operations --- */
980 typedef struct source_ops
{
981 const char *name
; /* Name of this source */
983 /* --- @option@ --- *
985 * Arguments: @scanner *sc@ = scanner to read from
986 * @source *s@ = pointer to source object, or zero if global
988 * Returns: Nonzero to claim the option.
990 * Use: Handles an option string from the configuration file.
993 int (*option
)(source */
*s*/
, scanner */
*sc*/
);
997 * Arguments: @scanner *sc@ = pointer to scanner to read from
999 * Returns: Pointer to a source object to claim, null to reject.
1001 * Use: Parses a source description from the configuration file.
1002 * Only the socket source is allowed to omit the prefix on a
1003 * source specification.
1006 source
*(*read
)(scanner */
*sc*/
);
1008 /* --- @attach@ --- *
1010 * Arguments: @source *s@ = pointer to source
1011 * @scanner *sc@ = scanner (for error reporting)
1012 * @target *t@ = pointer to target to attach
1016 * Use: Attaches a target to a source.
1019 void (*attach
)(source */
*s*/
, scanner */
*sc*/
, target */
*t*/
);
1021 /* --- @destroy@ --- *
1023 * Arguments: @source *s@ = pointer to source
1027 * Use: Destroys a source. Used when closing the system down, for
1028 * example as a result of a signal.
1031 void (*destroy
)(source */
*s*/
);
1035 /* --- @endpt_kill@ --- *
1037 * Arguments: @endpt *a@ = an endpoint
1041 * Use: Kills an endpoint. If the endpoint is joined to another, the
1042 * other endpoint is also killed, as is the connection between
1043 * them (and that's the tricky bit).
1046 extern void endpt_kill(endpt */
*a*/
);
1048 /* --- @endpt_killall@ --- *
1054 * Use: Destroys all current endpoint connections. Used when
1058 extern void endpt_killall(void);
1060 /* --- @endpt_join@ --- *
1062 * Arguments: @endpt *a@ = pointer to first endpoint
1063 * @endpt *b@ = pointer to second endpoint
1064 * @const char *desc@ = description of connection
1068 * Use: Joins two endpoints together. It's OK to join endpoints
1069 * which are already joined; in fact, the the right thing to do
1070 * when your endpoint decides that it's not pending any more is
1071 * to join it to its partner again.
1073 * If the endpoints are already connected then the description
1074 * string is ignored. The endpoint manager takes a copy of
1075 * the string, so you don't need to keep it around.
1078 extern void endpt_join(endpt */
*a*/
, endpt */
*b*/
, const char */
*desc*/
);
1080 /* --- @source_add@ --- *
1082 * Arguments: @source *s@ = pointer to a source
1086 * Use: Adds a source to the master list. Only do this for passive
1087 * sources (e.g., listening sockets), not active sources (e.g.,
1088 * executable programs).
1091 extern void source_add(source */
*s*/
);
1093 /* --- @source_remove@ --- *
1095 * Arguments: @source *s@ = pointer to a source
1099 * Use: Removes a source from the master list.
1102 extern void source_remove(source */
*s*/
);
1104 /* --- @source_killall@ --- *
1110 * Use: Frees all sources.
1113 extern void source_killall(void);
1115 /*----- The exec source and target ----------------------------------------*/
1117 extern source_ops xsource_ops
;
1118 extern target_ops xtarget_ops
;
1120 /* --- @exec_init@ --- *
1126 * Use: Initializes the executable problem source and target.
1129 extern void exec_init(void);
1131 /*----- The file source and target ----------------------------------------*/
1133 extern source_ops fsource_ops
;
1134 extern target_ops ftarget_ops
;
1136 /*----- The socket source and target --------------------------------------*/
1138 extern source_ops ssource_ops
;
1139 extern target_ops starget_ops
;
1141 /* --- @starget_connected@ --- *
1143 * Arguments: @int fd@ = file descriptor now ready for use
1144 * @void *p@ = pointer to an endpoint structure
1148 * Use: Handles successful connection of the target endpoint.
1151 extern void starget_connected(int /*fd*/, void */
*p*/
);
1153 /*----- Handling of file attributes ---------------------------------------*/
1155 /* --- File attribute options structure --- */
1157 typedef struct fattr
{
1163 /* --- Shared global options --- */
1165 extern fattr fattr_global
;
1167 /* --- @fattr_init@ --- *
1169 * Arguments: @fattr *f@ = pointer to file attributes
1173 * Use: Initializes a set of file attributes to default values.
1176 extern void fattr_init(fattr */
*f*/
);
1178 /* --- @fattr_option@ --- *
1180 * Arguments: @scanner *sc@ = pointer to scanner to read
1181 * @fattr *f@ = pointer to file attributes to set
1183 * Returns: Whether the option was clamed.
1185 * Use: Reads file attributes from a scanner.
1188 extern int fattr_option(scanner */
*sc*/
, fattr */
*f*/
);
1190 /* --- @fattr_apply@ --- *
1192 * Arguments: @const char *file@ = pointer to filename
1193 * @fattr *f@ = pointer to attribute set
1195 * Returns: @-1@ if it failed.
1197 * Use: Applies file attributes to a file. For best results, try to
1198 * create the file with the right permissions and so on. This
1199 * call will fix everything up, but there are potential races
1200 * which might catch you out if you're not careful.
1203 extern int fattr_apply(const char */
*file*/
, fattr */
*f*/
);
1205 /*----- Making privileged connections -------------------------------------*/
1207 /* --- @privconn_split@ --- *
1209 * Arguments: @sel_state *s@ = select state
1213 * Use: Splits off the privileged binding code into a separate
1217 extern void privconn_split(sel_state */
*s*/
);
1219 /* --- @privconn_adddest@ --- *
1221 * Arguments: @struct in_addr peer@ = address to connect to
1222 * @unsigned port@ = port to connect to
1224 * Returns: Index for this destination address, or @-1@ if not
1227 * Use: Adds a valid destination for a privileged connection.
1230 extern int privconn_adddest(struct in_addr
/*peer*/, unsigned /*port*/);
1232 /* --- @privconn_connect@ --- *
1234 * Arguments: @conn *c@ = connection structure to fill in
1235 * @sel_state *s@ = pointer to select state to attach to
1236 * @int i@ = address index to connect to
1237 * @struct in_addr bind@ = address to bind to
1238 * @void (*func)(int, void *)@ = function to call on connect
1239 * @void *p@ = argument for the function
1241 * Returns: Zero on success, @-1@ on failure.
1243 * Use: Sets up a privileged connection job.
1246 extern int privconn_connect(conn */
*c*/
, sel_state */
*s*/
,
1247 int /*i*/, struct in_addr
/*bind*/,
1248 void (*/
*func*/
)(int, void *), void */
*p*/
);
1250 /*----- Identifying remote clients ----------------------------------------*/
1252 typedef struct id_req
{
1253 struct sockaddr_in lsin
; /* Local address of connection */
1254 struct sockaddr_in rsin
; /* Remote address of connection */
1255 const char *desc
; /* Description of connection */
1256 const char *act
; /* Action taken by server */
1257 reffd
*r
; /* Pointer to file descriptor */
1260 /* --- @identify@ --- *
1262 * Arguments: @const id_req *q@ = pointer to request block
1266 * Use: Starts a background ident lookup and reverse-resolve job
1267 * which will, eventually, report a message to the system log.
1270 extern void identify(const id_req */
*q*/
);
1272 /*----- Host-based access control -----------------------------------------*/
1274 /* --- An access control entry --- */
1276 typedef struct acl_entry
{
1277 struct acl_entry
*next
; /* Next entry in the list */
1278 const struct acl_ops
*ops
; /* Operations for the ACL entry */
1279 unsigned act
; /* What to do with matching hosts */
1282 #define ACL_DENY 0 /* Deny access to matching conns */
1283 #define ACL_ALLOW 1 /* Allow access to matching conns */
1284 #define ACL_PERM 1u /* Bit mask for permission bit */
1286 /* --- Host-based access control --- */
1288 typedef struct acl_host
{
1289 acl_entry a
; /* Base structure */
1290 struct in_addr addr
, mask
; /* Address and netmask */
1293 /* --- ACL methods --- */
1295 typedef struct acl_ops
{
1296 int (*check
)(void */
*a*/
, struct in_addr
/*addr*/, unsigned /*port*/);
1297 void (*dump
)(void */
*a*/
, FILE */
*fp*/
);
1298 void (*free
)(void */
*a*/
);
1301 /* --- @acl_check@ --- *
1303 * Arguments: @acl_entry *a@ = pointer to ACL to check against
1304 * @struct in_addr addr@ = address to check
1305 * @unsigned port@ = port number to check
1306 * @int *act@ = verdict (should initially be @ACT_ALLOW@)
1308 * Returns: Zero if undecided, nonzero if a rule matched.
1310 * Use: Checks an address against an ACL.
1313 extern int acl_check(acl_entry */
*a*/
,
1314 struct in_addr
/*addr*/, unsigned /*port*/,
1317 /* --- @acl_dump@ --- *
1319 * Arguments: @acl_entry *a@ = pointer to ACL to dump
1320 * @FILE *fp@ = pointer to stream to dump on
1324 * Use: Dumps an access control list to an output stream.
1327 extern void acl_dump(acl_entry */
*a*/
, FILE */
*fp*/
);
1329 /* --- @acl_free@ --- *
1331 * Arguments: @acl_entry *a@ = pointer to a list of ACLs
1335 * Use: Frees all of the memory used by an ACL.
1338 extern void acl_free(acl_entry */
*a*/
);
1340 /* --- @acl_addhost@ --- *
1342 * Arguments: @acl_entry ***a@ = address of pointer to list tail
1343 * @unsigned act@ = what to do with matching addresses
1344 * @struct in_addr addr, mask@ = address and mask to match
1348 * Use: Adds a host-authentication entry to the end of an access
1352 extern void acl_addhost(acl_entry
***/
*a*/
, unsigned /*act*/,
1353 struct in_addr
/*addr*/, struct in_addr
/*mask*/);
1355 /* --- @acl_addpriv@ --- *
1357 * Arguments: @acl_entry ***a@ = address of pointer to list tail
1358 * @unsigned act@ = what to do with matching addresses
1362 * Use: Adds a privileged-port check to the end of an access control
1366 extern void acl_addpriv(acl_entry
***/
*a*/
, unsigned /*act*/);
1368 /*----- Network addresses -------------------------------------------------*/
1370 /* --- A generic socket address --- *
1372 * Not all systems understand @sa_len@ fields. (In particular, Linux
1373 * doesn't.) Some fairly ugly hacking is then performed on particular
1377 typedef struct addr
{
1378 struct addr_ops
*ops
;
1382 #define ADDRSZ(sz) (sizeof(addr) + (sz))
1384 /* --- Address configuration --- *
1386 * An address family will want to extend this.
1389 typedef struct addr_opts
{
1393 #define ADDRF_NOLOG 1u
1395 /* --- Address types --- *
1397 * For things like Internet addresses, source and destinations look
1407 /* --- Description of an address type handler --- */
1409 typedef struct addr_ops
{
1410 const char *name
; /* Protocol's internal name */
1414 * Arguments: @scanner *sc@ = pointer to scanner to read from
1415 * @unsigned type@ = type of address to be read
1417 * Returns: A filled-in socket address.
1419 * Use: Parses a textual representation of a socket address.
1422 addr
*(*read
)(scanner */
*sc*/
, unsigned /*type*/);
1424 /* --- @destroy@ --- *
1426 * Arguments: @addr *a@ = pointer to an address block
1430 * Use: Disposes of an address block in some suitable fashion.
1433 void (*destroy
)(addr */
*a*/
);
1435 /* --- @print@ --- *
1437 * Arguments: @addr *a@ = pointer to socket address to read
1438 * @unsigned type@ = type of address to be written
1439 * @dstr *d@ = string on which to write the description
1443 * Use: Writes a textual representation of a socket address to
1447 void (*print
)(addr */
*a*/
, unsigned /*type*/, dstr */
*d*/
);
1449 /* --- @initsrcopts@ --- *
1453 * Returns: A pointer to a protocol-specific data block for a listener
1455 * Use: Creates a data block for a listener. This is attached to the
1456 * listener data structure. Options can then be requested, and
1457 * are added to the block when necessary.
1460 addr_opts
*(*initsrcopts
)(void);
1462 /* --- @option@ --- *
1464 * Arguments: @scanner *sc@ = pointer to a scanner to read from
1465 * @unsigned type@ = kind of option this is
1466 * @addr_opts *ao@ = data block to modify (from @init@), or null
1468 * Returns: Nonzero to claim the option.
1470 * Use: Parses a source option, either global or listener-specific.
1473 int (*option
)(scanner */
*sc*/
, addr_opts */
*ao*/
, unsigned /*type*/);
1475 /* --- @confirm@ --- *
1477 * Arguments: @addr *a@ = pointer to an address structure
1478 * @unsigned type@ = kind of address this is
1479 * @addr_opts *ao@ = address options
1483 * Use: Called during initialization when an address is fully
1487 void (*confirm
)(addr */
*a*/
, unsigned /*type*/, addr_opts */
*ao*/
);
1489 /* --- @freesrcopts@ --- *
1491 * Arguments: @addr_opts *ao@ = data block to remove
1495 * Use: Throws away all the configuration data for an address type.
1498 void (*freesrcopts
)(addr_opts */
*ao*/
);
1502 * Arguments: @addr *a@ = the address to bind to
1503 * @addr_opts *ao@ = the address options
1505 * Returns: File descriptor of bound socket if OK, or @-1@ on error.
1507 * Use: Binds a listening socket. The tedious stuff with @listen@
1511 int (*bind
)(addr */
*a*/
, addr_opts */
*ao*/
);
1513 /* --- @unbind@ --- *
1515 * Arguments: @addr *a@ = pointer to an address
1519 * Use: Unbinds an address. This is used when tidying up. The main
1520 * purpose is to let the Unix-domain handler remove its socket
1521 * node from the filesystem.
1524 void (*unbind
)(addr */
*a*/
);
1526 /* --- @accept@ --- *
1528 * Arguments: @int fd@ = listening file descriptor
1529 * @addr_opts *ao@ = data block to get configuration from
1530 * @const char *desc@ = description of the listener
1532 * Returns: Pointer to a reference counted file descriptor.
1534 * Use: Accepts, verifies and logs an incoming connection.
1537 reffd
*(*accept
)(int /*fd*/, addr_opts */
*ao*/
, const char */
*desc*/
);
1539 /* --- @inittargopts@ --- *
1543 * Returns: A pointer to a protocol-specific data block for a connecter
1545 * Use: Creates a data block for a target. This is attached to the
1546 * target data structure. Options can then be requested, and
1547 * are added to the block when necessary.
1550 addr_opts
*(*inittargopts
)(void);
1552 /* --- @freetargopts@ --- *
1554 * Arguments: @addr_opts *ao@ = data block to remove
1558 * Use: Throws away all the configuration data for an address type.
1561 void (*freetargopts
)(addr_opts */
*ao*/
);
1563 /* --- @connect@ --- *
1565 * Arguments: @addr *a@ = destination address
1566 * @addr_opts *ao@ = target address options
1567 * @conn *c@ = connection structure
1568 * @endpt *e@ = endpoint structure
1570 * Returns: Zero if OK, @-1@ on some error.
1572 * Use: Requests that a connection be made, or at least set in
1573 * motion. An address may do one of these things:
1577 * * Call @starget_connected@ with @-1@ or a connected file
1578 * descriptor and the pointer @e@.
1580 * * Call @conn_init@ or @conn_fd@, giving @starget_connected@
1581 * and @e@ as the function to call.
1584 int (*connect
)(addr */
*a*/
, addr_opts */
*ao*/
, conn */
*c*/
, endpt */
*e*/
);
1588 /* --- Address types --- */
1590 extern addr_ops un_ops
;
1591 extern addr_ops inet_ops
;
1593 /*----- That's all, folks -------------------------------------------------*/