File: comm-common.h

package info (click to toggle)
secnet 0.6.8
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 1,956 kB
  • sloc: ansic: 15,234; python: 1,057; perl: 966; sh: 596; tcl: 484; java: 231; asm: 114; yacc: 89; php: 64; makefile: 48; awk: 40
file content (146 lines) | stat: -rw-r--r-- 5,059 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
 * This file is part of secnet.
 * See README for full list of copyright holders.
 *
 * secnet is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 * 
 * secnet is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * version 3 along with secnet; if not, see
 * https://www.gnu.org/licenses/gpl.html.
 */

#ifndef COMM_COMMON_H
#define COMM_COMMON_H

#include "secnet.h"
#include "util.h"

/*----- for all comms -----*/

struct comm_notify_entry {
    comm_notify_fn *fn;
    void *state;
    LIST_ENTRY(comm_notify_entry) entry;
};
LIST_HEAD(comm_notify_list, comm_notify_entry);

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;
    struct priomsg why_unwanted;
};

struct comm_clientinfo *comm_clientinfo_ignore(void *state, dict_t*,
					       struct cloc cloc);
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 commcommon*, 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;
   *     in that case, cc->why_unwanted has info
   * Ie, roughly like comm_notify_fn. */

void comm_apply(struct commcommon *cc, void *st);

#define COMM_APPLY(st,cc,prefix,desc,loc)		\
    NEW(st);						\
    (cc)->loc=loc;					\
    (cc)->cl.description=desc;				\
    (cc)->ops.clientinfo=comm_clientinfo_ignore;	\
    (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>;
     */

/*----- for udp-based comms -----*/

#define UDP_MAX_SOCKETS 3 /* 2 ought to do really */

#define MAX_AF MAX_RAW(AF_INET6,AF_INET)

struct udpsock {
    union iaddr addr;
    int fd;
    bool_t experienced[/*0=recv,1=send*/2][MAX_AF+1][/*success?*/2];
};

struct udpsocks {
    int n_socks;
    struct udpsock socks[UDP_MAX_SOCKETS];
    /* private for udp_socks_* */
    struct udpcommon *uc; /* link to parent, for cfg, notify list, etc. */
    struct poll_interest *interest;
    const char *desc;
};

struct udpcommon {
    struct commcommon cc;
    int port;
    string_t authbind;
    bool_t use_proxy;
    union iaddr proxy;
};

bool_t udp_make_socket(struct udpcommon *uc, struct udpsock *us,
		       int failmsgclass);
  /* Caller should have filled in ->addr.  Fills in us->fd,
     ->experienced; updates ->addr.  Logs any errors with lg_[v]perror. */
bool_t udp_import_socket(struct udpcommon *uc, struct udpsock *us,
			 int failmsgclass, int fd);
  /* Like udp_make_socket, but caller provides fd.  fd is not closed
     on error */

void udp_destroy_socket(struct udpcommon *uc, struct udpsock *us);
  /* Idempotent.  No errors are possible. */

const char *af_name(int af);
void udp_sock_experienced(struct log_if *lg, struct udpcommon *uc,
			  struct udpsocks *socks, struct udpsock *us,
			  const union iaddr *dest, int af /* 0 means any */,
			  int r, int errnoval);

void udp_socks_register(struct udpcommon *uc, struct udpsocks *socks,
			const char *desc);
void udp_socks_deregister(struct udpcommon *uc, struct udpsocks *socks);
void udp_socks_childpersist(struct udpcommon *uc, struct udpsocks *socks);

#define UDP_APPLY_STANDARD(st,uc,desc)					\
    (uc)->use_proxy=False;						\
    (uc)->authbind=dict_read_string(d,"authbind",False,"udp",(uc)->cc.loc); \
    (uc)->port=dict_read_number(d,"port",False,"udp",(uc)->cc.loc,0)
    /* void UDP_APPLY_STANDARD(SOMETHING *st, struct udpcommon *uc,
     *                         const char *desc);
     *   // Expects in scope:  dict_t *d=...;   as from COMM_APPLY_STANDARD
     */

#endif /*COMM_COMMON_H*/