X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=secnet.git;a=blobdiff_plain;f=secnet.h;h=6724698c2b7cc84f2c4de6296df6a01cc9abb9ea;hp=7d7eb4ff4b97c9b3f2334a6bf02626d9d2a49995;hb=ec2ae5fa0ae79baedb567ad18e09e17305aa89d1;hpb=7c9ca4bd3cf857d45d931f224fe6415b36d1cffe diff --git a/secnet.h b/secnet.h index 7d7eb4f..6724698 100644 --- a/secnet.h +++ b/secnet.h @@ -3,18 +3,42 @@ #ifndef secnet_h #define secnet_h +#define ADNS_FEATURE_MANYAF + #include "config.h" #include #include #include +#include +#include +#include +#include #include #include #include #include +#include + +#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 enum {False,True} bool_t; + +#define False (_Bool)0 +#define True (_Bool)1 +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 " \ __FILE__,__LINE__); } } while(0) @@ -92,7 +116,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 */ @@ -131,6 +155,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); +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; @@ -144,6 +171,16 @@ static const struct timeval *const tv_now = &tv_now_global; /***** 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 @@ -217,6 +254,7 @@ extern init_module random_module; extern init_module udp_module; extern init_module util_module; extern init_module site_module; +extern init_module transform_eax_module; extern init_module transform_cbcmac_module; extern init_module netlink_module; extern init_module rsa_module; @@ -254,11 +292,15 @@ struct buffer_if; /* Answers to queries are delivered to a function of this 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); + will be freed once resolve_answer_fn returns. naddrs is the actual + size of the array at addrs; was_naddrs is the number of addresses + 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, + const char *failwhy); 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; @@ -298,13 +340,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; - struct sockaddr_in sin; + 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 @@ -317,28 +355,44 @@ 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); + /* 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; - int32_t min_start_pad; - int32_t min_end_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; }; +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 + 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, ...) @@ -346,6 +400,13 @@ FORMAT(printf,3,4); 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, @@ -361,17 +422,19 @@ struct site_if { /* TRANSFORM interface */ /* A reversable transformation. Transforms buffer in-place; may add - data to start or end. Maximum amount of data to be added specified - in max_start_pad and max_end_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 state. A struct transform_if only represents a particular type of transformation; instances of the transformation (eg. with - particular key material) have a different C type. */ + particular key material) have a different C type. The same + secret key will be used in opposite directions between a pair of + secnets; one of these pairs will get direction==False, the other True. */ typedef struct transform_inst_if *transform_createinstance_fn(void *st); -typedef bool_t transform_setkey_fn(void *st, uint8_t *key, int32_t keylen); +typedef bool_t transform_setkey_fn(void *st, uint8_t *key, int32_t keylen, + bool_t direction); typedef bool_t transform_valid_fn(void *st); /* 0: no key; 1: ok */ typedef void transform_delkey_fn(void *st); typedef void transform_destroyinstance_fn(void *st); @@ -395,9 +458,8 @@ struct transform_inst_if { struct transform_if { void *st; - int32_t max_start_pad; /* these three are all <<< INT_MAX */ - int32_t max_end_pad; - 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; }; @@ -419,8 +481,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, - void *dst, int32_t max_start_pad, - int32_t max_end_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); @@ -471,7 +532,7 @@ struct buffer_if { 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 *****/ @@ -487,21 +548,25 @@ struct buffer_if { #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, - 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, - va_list)); + va_list)) + FORMAT(printf,4,0); 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); @@ -513,5 +578,19 @@ 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); + * 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, provided 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 */