chiark / gitweb /
site: Permit multiple peer addresses even if peer is static
[secnet.git] / secnet.h
index 2ccf161989507e43fbf1e326ca69a5c04b0ed55b..16d49596ba0baa2609c2431894fa6cd199524afe 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -9,14 +9,26 @@
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include <sys/poll.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <netinet/in.h>
 #include <sys/poll.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define MAX_PEER_ADDRS 5
+/* send at most this many copies; honour at most that many addresses */
+
+struct comm_if;
+struct comm_addr;
 
 typedef char *string_t;
 typedef const char *cstring_t;
 
 typedef char *string_t;
 typedef const char *cstring_t;
-typedef enum {False,True} bool_t;
+
+#define False (_Bool)0
+#define True  (_Bool)1
+typedef _Bool bool_t;
 
 #define ASSERT(x) do { if (!(x)) { fatal("assertion failed line %d file " \
                                         __FILE__,__LINE__); } } while(0)
 
 #define ASSERT(x) do { if (!(x)) { fatal("assertion failed line %d file " \
                                         __FILE__,__LINE__); } } while(0)
@@ -133,6 +145,9 @@ extern char *safe_strdup(const char *string, const char *message);
 extern void *safe_malloc(size_t size, const char *message);
 extern void *safe_malloc_ary(size_t size, size_t count, const char *message);
 
 extern void *safe_malloc(size_t size, const char *message);
 extern void *safe_malloc_ary(size_t size, size_t count, const char *message);
 
+void setcloexec(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, ...);
 
 extern uint64_t now_global;
 extern int sys_cmd(const char *file, const char *argc, ...);
 
 extern uint64_t now_global;
@@ -146,6 +161,16 @@ static const struct timeval *const tv_now = &tv_now_global;
 
 /***** END of utility functions *****/
 
 
 /***** END of utility functions *****/
 
+/***** START of max_start_pad handling *****/
+
+extern int32_t site_max_start_pad, transform_max_start_pad,
+    comm_max_start_pad;
+
+void update_max_start_pad(int32_t *our_module_global, int32_t our_instance);
+int32_t calculate_max_start_pad(void);
+
+/***** END of max_start_pad handling *****/
+
 /***** SCHEDULING support */
 
 /* If nfds_io is insufficient for your needs, set it to the required
 /***** SCHEDULING support */
 
 /* If nfds_io is insufficient for your needs, set it to the required
@@ -259,9 +284,10 @@ struct buffer_if;
    type. 'address' will be NULL if there was a problem with the query. It
    will be freed once resolve_answer_fn returns. It is in network byte
    order. */
    type. 'address' will be NULL if there was a problem with the query. It
    will be freed once resolve_answer_fn returns. It is in network byte
    order. */
-/* XXX extend to be able to provide multiple answers */
-typedef void resolve_answer_fn(void *st, struct in_addr *addr);
+typedef void resolve_answer_fn(void *st, const struct comm_addr *addrs,
+                              int naddrs);
 typedef bool_t resolve_request_fn(void *st, cstring_t name,
 typedef bool_t resolve_request_fn(void *st, cstring_t name,
+                                 int remoteport, struct comm_if *comm,
                                  resolve_answer_fn *cb, void *cst);
 struct resolver_if {
     void *st;
                                  resolve_answer_fn *cb, void *cst);
 struct resolver_if {
     void *st;
@@ -320,27 +346,36 @@ typedef void comm_release_notify_fn(void *commst, void *nst,
                                    comm_notify_fn *fn);
 typedef bool_t comm_sendmsg_fn(void *commst, struct buffer_if *buf,
                               const struct comm_addr *dest);
                                    comm_notify_fn *fn);
 typedef bool_t comm_sendmsg_fn(void *commst, struct buffer_if *buf,
                               const struct comm_addr *dest);
+  /* Only returns false if (we know that) the local network
+   * environment is such that this address cannot work; transient
+   * or unknown/unexpected failures return true. */
 typedef const char *comm_addr_to_string_fn(void *commst,
                                           const struct comm_addr *ca);
         /* Returned string is in a static buffer. */
 struct comm_if {
     void *st;
 typedef const char *comm_addr_to_string_fn(void *commst,
                                           const struct comm_addr *ca);
         /* Returned string is in a static buffer. */
 struct comm_if {
     void *st;
-    int32_t min_start_pad;
     comm_request_notify_fn *request_notify;
     comm_release_notify_fn *release_notify;
     comm_sendmsg_fn *sendmsg;
     comm_addr_to_string_fn *addr_to_string;
 };
 
     comm_request_notify_fn *request_notify;
     comm_release_notify_fn *release_notify;
     comm_sendmsg_fn *sendmsg;
     comm_addr_to_string_fn *addr_to_string;
 };
 
+static inline const char *comm_addr_to_string(const struct comm_addr *ca)
+{
+    return ca->comm->addr_to_string(ca->comm->st, ca);
+}
+
 /* LOG interface */
 
 /* LOG interface */
 
+#define LOG_MESSAGE_BUFLEN 1023
+
 typedef void log_msg_fn(void *st, int class, const char *message, ...);
 typedef void log_vmsg_fn(void *st, int class, const char *message,
                         va_list args);
 struct log_if {
     void *st;
 typedef void log_msg_fn(void *st, int class, const char *message, ...);
 typedef void log_vmsg_fn(void *st, int class, const char *message,
                         va_list args);
 struct log_if {
     void *st;
-    log_msg_fn *log;
-    log_vmsg_fn *vlog;
+    log_vmsg_fn *vlogfn; /* printf format checking.  Use [v]slilog instead */
+    char buff[LOG_MESSAGE_BUFLEN+1];
 };
 /* (convenience functions, defined in util.c) */
 extern void slilog(struct log_if *lf, int class, const char *message, ...)
 };
 /* (convenience functions, defined in util.c) */
 extern void slilog(struct log_if *lf, int class, const char *message, ...)
@@ -348,6 +383,13 @@ FORMAT(printf,3,4);
 extern void vslilog(struct log_if *lf, int class, const char *message, va_list)
 FORMAT(printf,3,0);
 
 extern void vslilog(struct log_if *lf, int class, const char *message, va_list)
 FORMAT(printf,3,0);
 
+/* Versions which take (parts of) (multiple) messages, using \n to
+ * distinguish one message from another. */
+extern void slilog_part(struct log_if *lf, int class, const char *message, ...)
+FORMAT(printf,3,4);
+extern void vslilog_part(struct log_if *lf, int class, const char *message,
+                        va_list) FORMAT(printf,3,0);
+
 /* SITE interface */
 
 /* Pretty much a placeholder; allows starting and stopping of processing,
 /* SITE interface */
 
 /* Pretty much a placeholder; allows starting and stopping of processing,
@@ -363,8 +405,7 @@ struct site_if {
 /* TRANSFORM interface */
 
 /* A reversable transformation. Transforms buffer in-place; may add
 /* TRANSFORM interface */
 
 /* A reversable transformation. Transforms buffer in-place; may add
-   data to start or end. Maximum amount of data to be added before
-   the packet specified in max_start_pad. (Reverse transformations decrease
+   data to start or end. (Reverse transformations decrease
    length, of course.)  Transformations may be key-dependent, in which
    case key material is passed in at initialisation time. They may
    also depend on internal factors (eg. time) and keep internal
    length, of course.)  Transformations may be key-dependent, in which
    case key material is passed in at initialisation time. They may
    also depend on internal factors (eg. time) and keep internal
@@ -396,13 +437,12 @@ struct transform_inst_if {
     transform_apply_fn *forwards;
     transform_apply_fn *reverse;
     transform_destroyinstance_fn *destroy;
     transform_apply_fn *forwards;
     transform_apply_fn *reverse;
     transform_destroyinstance_fn *destroy;
-    int32_t max_start_pad; /* same as from transform_if */
 };
 
 struct transform_if {
     void *st;
 };
 
 struct transform_if {
     void *st;
-    int32_t max_start_pad; /* these two are both <<< INT_MAX */
-    int32_t keylen; /* 0 means give the transform exactly as much as there is */
+    int capab_transformnum;
+    int32_t keylen; /* <<< INT_MAX */
     transform_createinstance_fn *create;
 };
 
     transform_createinstance_fn *create;
 };
 
@@ -424,7 +464,7 @@ typedef void netlink_deliver_fn(void *st, struct buffer_if *buf);
 #define MAXIMUM_LINK_QUALITY 3
 typedef void netlink_link_quality_fn(void *st, uint32_t quality);
 typedef void netlink_register_fn(void *st, netlink_deliver_fn *deliver,
 #define MAXIMUM_LINK_QUALITY 3
 typedef void netlink_link_quality_fn(void *st, uint32_t quality);
 typedef void netlink_register_fn(void *st, netlink_deliver_fn *deliver,
-                                void *dst, int32_t max_start_pad);
+                                void *dst, uint32_t *localmtu_r /* NULL ok */);
 typedef void netlink_output_config_fn(void *st, struct buffer_if *buf);
 typedef bool_t netlink_check_config_fn(void *st, struct buffer_if *buf);
 typedef void netlink_set_mtu_fn(void *st, int32_t new_mtu);
 typedef void netlink_output_config_fn(void *st, struct buffer_if *buf);
 typedef bool_t netlink_check_config_fn(void *st, struct buffer_if *buf);
 typedef void netlink_set_mtu_fn(void *st, int32_t new_mtu);
@@ -475,7 +515,7 @@ struct buffer_if {
     uint8_t *base;
     uint8_t *start;
     int32_t size; /* Size of buffer contents */
     uint8_t *base;
     uint8_t *start;
     int32_t size; /* Size of buffer contents */
-    int32_t len; /* Total length allocated at base */
+    int32_t alloclen; /* Total length allocated at base */
 };
 
 /***** LOG functions *****/
 };
 
 /***** LOG functions *****/
@@ -491,21 +531,25 @@ struct buffer_if {
 #define M_FATAL               0x100
 
 /* The fatal() family of functions require messages that do not end in '\n' */
 #define M_FATAL               0x100
 
 /* The fatal() family of functions require messages that do not end in '\n' */
-extern NORETURN(fatal(const char *message, ...));
-extern NORETURN(fatal_perror(const char *message, ...));
-extern NORETURN(fatal_status(int status, const char *message, ...));
-extern NORETURN(fatal_perror_status(int status, const char *message, ...));
+extern NORETURN(fatal(const char *message, ...)) FORMAT(printf,1,2);
+extern NORETURN(fatal_perror(const char *message, ...)) FORMAT(printf,1,2);
+extern NORETURN(fatal_status(int status, const char *message, ...))
+       FORMAT(printf,2,3);
+extern NORETURN(fatal_perror_status(int status, const char *message, ...))
+       FORMAT(printf,2,3);
 
 /* The cfgfatal() family of functions require messages that end in '\n' */
 extern NORETURN(cfgfatal(struct cloc loc, cstring_t facility,
 
 /* The cfgfatal() family of functions require messages that end in '\n' */
 extern NORETURN(cfgfatal(struct cloc loc, cstring_t facility,
-                        const char *message, ...));
+                        const char *message, ...)) FORMAT(printf,3,4);
 extern void cfgfile_postreadcheck(struct cloc loc, FILE *f);
 extern NORETURN(vcfgfatal_maybefile(FILE *maybe_f, struct cloc loc,
                                    cstring_t facility, const char *message,
 extern void cfgfile_postreadcheck(struct cloc loc, FILE *f);
 extern NORETURN(vcfgfatal_maybefile(FILE *maybe_f, struct cloc loc,
                                    cstring_t facility, const char *message,
-                                   va_list));
+                                   va_list))
+    FORMAT(printf,4,0);
 extern NORETURN(cfgfatal_maybefile(FILE *maybe_f, struct cloc loc,
                                   cstring_t facility,
 extern NORETURN(cfgfatal_maybefile(FILE *maybe_f, struct cloc loc,
                                   cstring_t facility,
-                                  const char *message, ...));
+                                  const char *message, ...))
+    FORMAT(printf,4,5);
 
 extern void Message(uint32_t class, const char *message, ...)
     FORMAT(printf,2,3);
 
 extern void Message(uint32_t class, const char *message, ...)
     FORMAT(printf,2,3);
@@ -518,4 +562,17 @@ extern void log_from_fd(int fd, cstring_t prefix, struct log_if *log);
 
 #define FILLZERO(obj) (memset(&(obj),0,sizeof((obj))))
 
 
 #define FILLZERO(obj) (memset(&(obj),0,sizeof((obj))))
 
+/*
+ * void COPY_OBJ(  OBJECT& dst, const OBJECT& src);
+ * void COPY_ARRAY(OBJECT *dst, const OBJECT *src, INTEGER count);
+ *   // Typesafe: we check that the type OBJECT is the same in both cases.
+ *   // It is OK to use COPY_OBJ on an array object, proviced it's
+ *   // _actually_ the whole array object and not decayed into a
+ *   // pointer (e.g. a formal parameter).
+ */
+#define COPY_OBJ(dst,src) \
+    (&(dst)==&(src), memcpy(&(dst),&(src),sizeof((dst))))
+#define COPY_ARRAY(dst,src,count) \
+    (&(dst)[0]==&(src)[0], memcpy((dst),(src),sizeof((dst)[0])*(count)))
+
 #endif /* secnet_h */
 #endif /* secnet_h */