chiark / gitweb /
poll: Introduce and use BEFOREPOLL_WANT_FDS
[secnet.git] / secnet.h
index f458f8a345724e3cdb78b2dcf25b7ac1b873261f..0e2e1f7819057a17b8911a7c1647cb0cd70508de 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -3,6 +3,8 @@
 #ifndef secnet_h
 #define secnet_h
 
+#define ADNS_FEATURE_MANYAF
+
 #include "config.h"
 #include <stdlib.h>
 #include <stdarg.h>
 #include <assert.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 #include <sys/poll.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
+#include <bsd/sys/queue.h>
+
 #define MAX_PEER_ADDRS 5
 /* send at most this many copies; honour at most that many addresses */
 
@@ -33,6 +38,9 @@ typedef _Bool bool_t;
 union iaddr {
     struct sockaddr sa;
     struct sockaddr_in sin;
+#ifdef CONFIG_IPV6
+    struct sockaddr_in6 sin6;
+#endif
 };
 
 #define ASSERT(x) do { if (!(x)) { fatal("assertion failed line %d file " \
@@ -111,7 +119,7 @@ extern cstring_t *dict_keys(dict_t *dict);
 
 /* List-manipulation functions */
 extern list_t *list_new(void);
-extern int32_t list_length(list_t *a);
+extern int32_t list_length(const list_t *a);
 extern list_t *list_append(list_t *a, item_t *i);
 extern list_t *list_append_list(list_t *a, list_t *b);
 /* Returns an item from the list (index starts at 0), or NULL */
@@ -133,6 +141,14 @@ extern uint32_t dict_read_number(dict_t *dict, cstring_t key, bool_t required,
   /* return value can safely be assigned to int32_t */
 extern bool_t dict_read_bool(dict_t *dict, cstring_t key, bool_t required,
                             cstring_t desc, struct cloc loc, bool_t def);
+const char **dict_read_string_array(dict_t *dict, cstring_t key,
+                                   bool_t required, cstring_t desc,
+                                   struct cloc loc, const char *const *def);
+  /* Return value is a NULL-terminated array obtained from malloc;
+   * Individual string values are still owned by config file machinery
+   * and must not be modified or freed.  Returns NULL if key not
+   * found. */
+
 struct flagstr {
     cstring_t name;
     uint32_t value;
@@ -185,6 +201,16 @@ typedef int beforepoll_fn(void *st, struct pollfd *fds, int *nfds_io,
                          int *timeout_io);
 typedef void afterpoll_fn(void *st, struct pollfd *fds, int nfds);
 
+/* void BEFOREPOLL_WANT_FDS(int want);
+ *   Expects: int *nfds_io;
+ *   Can perform non-local exit.
+ * Checks whether there is space for want fds.  If so, sets *nfds_io.
+ * If not, sets *nfds_io and returns. */
+#define BEFOREPOLL_WANT_FDS(want) do{                          \
+    if (*nfds_io<(want)) { *nfds_io=(want); return ERANGE; }   \
+    *nfds_io=(want);                                           \
+  }while(0)
+
 /* Register interest in the main loop of the program. Before a call
    to poll() your supplied beforepoll function will be called. After
    the call to poll() the supplied afterpoll function will be called.
@@ -292,7 +318,10 @@ struct buffer_if;
    actually found in the DNS, which may be bigger if addrs is equal
    to MAX_PEER_ADDRS (ie there were too many). */
 typedef void resolve_answer_fn(void *st, const struct comm_addr *addrs,
-                              int naddrs, int was_naddrs);
+                              int naddrs, int was_naddrs,
+                              const char *name, const char *failwhy);
+  /* name is the same ptr as passed to request, so its lifetime must
+   * be suitable*/
 typedef bool_t resolve_request_fn(void *st, cstring_t name,
                                  int remoteport, struct comm_if *comm,
                                  resolve_answer_fn *cb, void *cst);
@@ -334,13 +363,9 @@ struct rsaprivkey_if {
 struct comm_addr {
     /* This struct is pure data; in particular comm's clients may
        freely copy it. */
-    /* Everyone is also guaranteed that all padding is set to zero, ie
-       that comm_addrs referring to semantically identical peers will
-       compare equal with memcmp.  Anyone who constructs a comm_addr
-       must start by memsetting it with FILLZERO, or some
-       equivalent. */
     struct comm_if *comm;
     union iaddr ia;
+    int ix; /* see comment `Re comm_addr.ix' in udp.c */
 };
 
 /* Return True if the packet was processed, and shouldn't be passed to
@@ -367,11 +392,19 @@ struct comm_if {
     comm_addr_to_string_fn *addr_to_string;
 };
 
+bool_t iaddr_equal(const union iaddr *ia, const union iaddr *ib);
+
 static inline const char *comm_addr_to_string(const struct comm_addr *ca)
 {
     return ca->comm->addr_to_string(ca->comm->st, 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);
+}
+
 /* LOG interface */
 
 #define LOG_MESSAGE_BUFLEN 1023
@@ -568,6 +601,7 @@ extern void log_from_fd(int fd, cstring_t prefix, struct log_if *log);
 #define STRING(x) STRING2(x)
 
 #define FILLZERO(obj) (memset(&(obj),0,sizeof((obj))))
+#define ARRAY_SIZE(ary) (sizeof((ary))/sizeof((ary)[0]))
 
 /*
  * void COPY_OBJ(  OBJECT& dst, const OBJECT& src);