chiark / gitweb /
string_item_to_iaddr: Actually set port if !CONFIG_IPV6
[secnet.git] / secnet.h
index 2c55a329313c5c8c89c1b87934381455e2422cce..8e5dad05d964b55cdfa9a0a735f753100b0690d6 100644 (file)
--- a/secnet.h
+++ b/secnet.h
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <fnmatch.h>
 #include <sys/poll.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <sys/time.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -58,6 +60,16 @@ extern struct log_if *system_log;
 /* from process.c */
 extern void start_signal_handling(void);
 
+void afterfork(void);
+/* Must be called before exec in every child made after
+   start_signal_handling.  Safe to call in earlier children too. */
+
+void childpersist_closefd_hook(void *fd_p, uint32_t newphase);
+/* Convenience hook function for use with add_hook PHASE_CHILDPERSIST.
+   With `int fd' in your state struct, pass fd_p=&fd.  The hook checks
+   whether fd>=0, so you can use it for an fd which is only sometimes
+   open.  This function will set fd to -1, so it is idempotent. */
+
 /***** CONFIGURATION support *****/
 
 extern bool_t just_check_config; /* If True then we're going to exit after
@@ -168,7 +180,18 @@ extern void *safe_malloc_ary(size_t size, size_t count, const char *message);
 extern void *safe_realloc_ary(void *p, size_t size, size_t count,
                              const char *message);
 
+#define NEW(p)                                 \
+    ((p)=safe_malloc(sizeof(*(p)),             \
+                    __FILE__ ":" #p))
+#define NEW_ARY(p,count)                                       \
+    ((p)=safe_malloc_ary(sizeof(*(p)),(count),                 \
+                        __FILE__ ":" #p "[" #count "]"))
+#define REALLOC_ARY(p,count)                                   \
+    ((p)=safe_realloc_ary((p),sizeof(*(p)),(count),            \
+                         __FILE__ ":" #p "[" #count "]"))
+
 void setcloexec(int fd); /* cannot fail */
+void setnonblock(int fd); /* cannot fail */
 void pipe_cloexec(int fd[2]); /* pipe(), setcloexec() twice; cannot fail */
 
 extern int sys_cmd(const char *file, const char *argc, ...);
@@ -251,10 +274,18 @@ enum phase {
     PHASE_DROPPRIV,            /* Last chance for privileged operations */
     PHASE_RUN,
     PHASE_SHUTDOWN,            /* About to die; delete key material, etc. */
+    PHASE_CHILDPERSIST,        /* Forked long-term child: close fds, etc. */
     /* Keep this last: */
     NR_PHASES,
 };
 
+/* Each module should, in its CHILDPERSIST hooks, close all fds which
+   constitute ownership of important operating system resources, or
+   which are used for IPC with other processes who want to get the
+   usual disconnection effects if the main secnet process dies.
+   CHILDPERSIST hooks are not run if the child is going to exec;
+   so fds such as described above should be CLOEXEC too. */
+
 typedef void hook_fn(void *self, uint32_t newphase);
 bool_t add_hook(uint32_t phase, hook_fn *f, void *state);
 bool_t remove_hook(uint32_t phase, hook_fn *f, void *state);
@@ -262,12 +293,20 @@ bool_t remove_hook(uint32_t phase, hook_fn *f, void *state);
 extern uint32_t current_phase;
 extern void enter_phase(uint32_t new_phase);
 
+void phase_hooks_init(void); /* for main() only */
+void clear_phase_hooks(uint32_t phase); /* for afterfork() */
+
 /* Some features (like netlink 'soft' routes) require that secnet
    retain root privileges.  They should indicate that here when
    appropriate. */
 extern bool_t require_root_privileges;
 extern cstring_t require_root_privileges_explanation;
 
+/* Some modules may want to know whether secnet is going to drop
+   privilege, so that they know whether to do privsep.  Call only
+   in phases SETUP and later. */
+bool_t will_droppriv(void);
+
 /***** END of program lifetime support *****/
 
 /***** MODULE support *****/
@@ -282,6 +321,7 @@ extern void init_builtin_modules(dict_t *dict);
 extern init_module resolver_module;
 extern init_module random_module;
 extern init_module udp_module;
+extern init_module polypath_module;
 extern init_module util_module;
 extern init_module site_module;
 extern init_module transform_eax_module;
@@ -378,7 +418,7 @@ struct comm_addr {
 };
 
 /* Return True if the packet was processed, and shouldn't be passed to
-   any other potential receivers. */
+   any other potential receivers. (buf is freed iff True returned.) */
 typedef bool_t comm_notify_fn(void *state, struct buffer_if *buf,
                              const struct comm_addr *source);
 typedef void comm_request_notify_fn(void *commst, void *nst,
@@ -401,7 +441,8 @@ struct comm_if {
     comm_addr_to_string_fn *addr_to_string;
 };
 
-bool_t iaddr_equal(const union iaddr *ia, const union iaddr *ib);
+bool_t iaddr_equal(const union iaddr *ia, const union iaddr *ib,
+                  bool_t ignoreport);
 
 static inline const char *comm_addr_to_string(const struct comm_addr *ca)
 {
@@ -411,7 +452,7 @@ static inline const char *comm_addr_to_string(const struct comm_addr *ca)
 static inline bool_t comm_addr_equal(const struct comm_addr *a,
                                     const struct comm_addr *b)
 {
-    return a->comm==b->comm && iaddr_equal(&a->ia,&b->ia);
+    return a->comm==b->comm && iaddr_equal(&a->ia,&b->ia,False);
 }
 
 /* LOG interface */
@@ -587,6 +628,19 @@ extern NORETURN(fatal_status(int status, const char *message, ...))
 extern NORETURN(fatal_perror_status(int status, const char *message, ...))
        FORMAT(printf,2,3);
 
+/* Convenient nonfatal logging.  Requires message that does not end in '\n'.
+ * If class contains M_FATAL, exits (after entering PHASE_SHUTDOWN).
+ * lg, errnoval and loc may sensibly be 0.  desc must NOT be 0.
+ * lg_[v]perror save and restore errno. */
+void lg_vperror(struct log_if *lg, const char *desc, struct cloc *loc,
+               int class, int errnoval, const char *fmt, va_list al)
+    FORMAT(printf,6,0);
+void lg_perror(struct log_if *lg, const char *desc, struct cloc *loc,
+              int class, int errnoval, const char *fmt, ...)
+    FORMAT(printf,6,7);
+void lg_exitstatus(struct log_if *lg, const char *desc, struct cloc *loc,
+                  int class, int status, const char *progname);
+
 /* The cfgfatal() family of functions require messages that end in '\n' */
 extern NORETURN(cfgfatal(struct cloc loc, cstring_t facility,
                         const char *message, ...)) FORMAT(printf,3,4);