OBJECTS:=secnet.o util.o conffile.yy.o conffile.tab.o conffile.o modules.o \
resolver.o random.o udp.o site.o transform-cbcmac.o transform-eax.o \
+ comm-common.o \
netlink.o rsa.o dh.o serpent.o serpentbe.o \
md5.o sha512.o tun.o slip.o sha1.o ipaddr.o log.o \
process.o @LIBOBJS@ \
--- /dev/null
+
+#include "secnet.h"
+#include "comm-common.h"
+
+void comm_request_notify(void *commst, void *nst, comm_notify_fn *fn)
+{
+ struct commcommon *st=commst;
+ struct comm_notify_entry *n;
+
+ n=safe_malloc(sizeof(*n),"comm_request_notify");
+ n->fn=fn;
+ n->state=nst;
+ LIST_INSERT_HEAD(&st->notify, n, entry);
+}
+
+void comm_release_notify(void *commst, void *nst, comm_notify_fn *fn)
+{
+ struct commcommon *st=commst;
+ struct comm_notify_entry *n, *t;
+
+ /* XXX untested */
+ LIST_FOREACH_SAFE(n, &st->notify, entry, t) {
+ if (n->state==nst && n->fn==fn) {
+ LIST_REMOVE(n, entry);
+ free(n);
+ }
+ }
+}
+
+bool_t comm_notify(struct comm_notify_list *notify,
+ struct buffer_if *buf, const struct comm_addr *ca)
+{
+ struct comm_notify_entry *n;
+
+ LIST_FOREACH(n, notify, entry) {
+ if (n->fn(n->state, buf, ca)) {
+ return True;
+ }
+ }
+ return False;
+}
+
+void comm_apply(struct commcommon *cc, void *st)
+{
+ assert(cc==st);
+ cc->cl.type=CL_COMM;
+ cc->cl.apply=NULL;
+ cc->cl.interface=&cc->ops;
+ cc->ops.st=cc;
+ cc->ops.request_notify=comm_request_notify;
+ cc->ops.release_notify=comm_release_notify;
+ LIST_INIT(&cc->notify);
+ cc->rbuf=NULL;
+}
--- /dev/null
+
+#ifndef COMM_COMMON_H
+#define COMM_COMMON_H
+
+#include "secnet.h"
+
+struct comm_notify_entry {
+ comm_notify_fn *fn;
+ void *state;
+ LIST_ENTRY(comm_notify_entry) entry;
+};
+LIST_HEAD(comm_notify_list, comm_notify_entry) notify;
+
+struct commcommon { /* must be first so that void* is comm_common* */
+ closure_t cl;
+ struct comm_if ops;
+ struct cloc loc;
+ struct comm_notify_list notify;
+ struct buffer_if *rbuf;
+};
+
+void comm_request_notify(void *commst, void *nst, comm_notify_fn *fn);
+void comm_release_notify(void *commst, void *nst, comm_notify_fn *fn);
+
+bool_t comm_notify(struct comm_notify_list *notify, struct buffer_if *buf,
+ const struct comm_addr *ca);
+ /* Either: returns True, with message delivered and buffer freed.
+ * Or: False, if no-one wanted it - buffer still allocd'd.
+ * Ie, like comm_notify_fn. */
+
+void comm_apply(struct commcommon *cc, void *st);
+
+#define COMM_APPLY(st,cc,prefix,desc,loc) \
+ (st)=safe_malloc(sizeof(*(st)), desc "_apply"); \
+ (cc)->loc=loc; \
+ (cc)->cl.description=desc; \
+ (cc)->ops.sendmsg=prefix##sendmsg; \
+ (cc)->ops.addr_to_string=prefix##addr_to_string; \
+ comm_apply((cc),(st))
+ /* void COMM_APPLY(SOMETHING *st, struct commcommon *FUNCTIONOF(st),
+ * prefix, "DESC", struct cloc loc);
+ * // Expects in scope: prefix##sendmsg, prefix##addr_to_string.
+ */
+
+#define COMM_APPLY_STANDARD(st,cc,desc,args) \
+ item_t *item=list_elem(args,0); \
+ if (!item || item->type!=t_dict) { \
+ cfgfatal((cc)->loc,desc,"first argument must be a dictionary\n"); \
+ } \
+ dict_t *d=item->data.dict; \
+ (cc)->rbuf=find_cl_if(d,"buffer",CL_BUFFER,True,desc,(cc)->loc)
+ /* void COMM_APPLY_STANDARD(SOMETHING *st, struct commcommon *cc,
+ * const char *desc, list_t *args);
+ * // Declares:
+ * // item_t *item = <undefined>;
+ * // dict_t *dict = <construction dictionary argument>;
+ */
+
+#endif /*COMM_COMMON_H*/
};
/* 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,
#include "unaligned.h"
#include "ipaddr.h"
#include "magic.h"
+#include "comm-common.h"
static beforepoll_fn udp_beforepoll;
static afterpoll_fn udp_afterpoll;
-static comm_request_notify_fn request_notify;
-static comm_release_notify_fn release_notify;
static comm_sendmsg_fn udp_sendmsg;
-struct comm_notify_entry {
- comm_notify_fn *fn;
- void *state;
- LIST_ENTRY(comm_notify_entry) entry;
-};
-LIST_HEAD(comm_notify_list, comm_notify_entry) notify;
-
#define UDP_MAX_SOCKETS 3 /* 2 ought to do really */
struct udpsock {
};
struct udp {
- closure_t cl;
- struct comm_if ops;
- struct cloc loc;
+ struct commcommon cc;
int n_socks;
struct udpsock socks[UDP_MAX_SOCKETS];
string_t authbind;
- struct buffer_if *rbuf;
- struct comm_notify_list notify;
bool_t use_proxy;
union iaddr proxy;
};
* description of the source of an incoming packet.
*/
-static const char *addr_to_string(void *commst, const struct comm_addr *ca) {
+static const char *udp_addr_to_string(void *commst, const struct comm_addr *ca)
+{
struct udp *st=commst;
struct udp *socks=st; /* for now */
static char sbuf[100];
static void udp_afterpoll(void *state, struct pollfd *fds, int nfds)
{
struct udp *st=state;
+ struct commcommon *cc=&st->cc;
struct udp *socks=st; /* for now */
- struct udp *cc=st; /* for now */
struct udp *uc=st; /* for now */
union iaddr from;
socklen_t fromlen;
- struct comm_notify_entry *n;
bool_t done;
int rv;
int i;
ca.comm=&cc->ops;
ca.ia=from;
ca.ix=i;
- done=False;
- LIST_FOREACH(n, &cc->notify, entry) {
- if (n->fn(n->state, cc->rbuf, &ca)) {
- done=True;
- break;
- }
- }
+ done=comm_notify(&cc->notify, cc->rbuf, &ca);
if (!done) {
uint32_t msgtype;
if (cc->rbuf->size>12 /* prevents traffic amplification */
}
}
-static void request_notify(void *commst, void *nst, comm_notify_fn *fn)
-{
- struct udp *st=commst;
- struct udp *cc=st; /* for now */
- struct comm_notify_entry *n;
-
- n=safe_malloc(sizeof(*n),"request_notify");
- n->fn=fn;
- n->state=nst;
- LIST_INSERT_HEAD(&cc->notify, n, entry);
-}
-
-static void release_notify(void *commst, void *nst, comm_notify_fn *fn)
-{
- struct udp *st=commst;
- struct udp *cc=st; /* for now */
- struct comm_notify_entry *n, *t;
-
- /* XXX untested */
- LIST_FOREACH_SAFE(n, &cc->notify, entry, t) {
- if (n->state==nst && n->fn==fn) {
- LIST_REMOVE(n, entry);
- free(n);
- }
- }
-}
-
static bool_t udp_sendmsg(void *commst, struct buffer_if *buf,
const struct comm_addr *dest)
{
static void udp_make_socket(struct udp *st, struct udpsock *us)
{
const union iaddr *addr=&us->addr;
- struct udp *cc=st; /* for now */
+ struct commcommon *cc=&st->cc; /* for now */
struct udp *uc=st; /* for now */
us->fd=socket(addr->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
if (us->fd<0) {
list_t *args)
{
struct udp *st;
- item_t *item;
list_t *caddrl;
- dict_t *d;
list_t *l;
uint32_t a;
int i;
- st=safe_malloc(sizeof(*st),"udp_apply(st)");
- struct udp *cc=st; /* for now */
+ COMM_APPLY(st,&st->cc,udp_,"udp",loc);
+ struct commcommon *cc=&st->cc; /* for now */
struct udp *uc=st; /* for now */
struct udp *socks=st; /* for now */
- cc->loc=loc;
- cc->cl.description="udp";
- cc->cl.type=CL_COMM;
- cc->cl.apply=NULL;
- cc->cl.interface=&cc->ops;
- cc->ops.st=st;
- cc->ops.request_notify=request_notify;
- cc->ops.release_notify=release_notify;
- cc->ops.sendmsg=udp_sendmsg;
- cc->ops.addr_to_string=addr_to_string;
+
uc->use_proxy=False;
- LIST_INIT(&cc->notify);
- item=list_elem(args,0);
- if (!item || item->type!=t_dict) {
- cfgfatal(cc->loc,"udp","first argument must be a dictionary\n");
- }
- d=item->data.dict;
+ COMM_APPLY_STANDARD(st,&st->cc,"udp",args);
int port=dict_read_number(d,"port",True,"udp",cc->loc,0);
us->fd=-1;
}
- cc->rbuf=find_cl_if(d,"buffer",CL_BUFFER,True,"udp",cc->loc);
uc->authbind=dict_read_string(d,"authbind",False,"udp",cc->loc);
l=dict_lookup(d,"proxy");
if (l) {