typedef struct peer_iter { sym_iter i; } peer_iter;
+typedef struct udpsocket {
+ sel_file sf; /* Selector for the socket */
+ unsigned port; /* Chosen port number */
+} udpsocket;
+
typedef struct ping {
struct ping *next, *prev; /* Links to next and previous */
peer *p; /* Peer so we can free it */
extern octet buf_i[PKBUFSZ], buf_o[PKBUFSZ], buf_t[PKBUFSZ], buf_u[PKBUFSZ];
extern const tunnel_ops *tunnels[]; /* Table of tunnels (0-term) */
extern const tunnel_ops *tun_default; /* Default tunnel to use */
-extern sel_file udpsock[NADDRFAM]; /* The master UDP sockets */
+extern udpsocket udpsock[NADDRFAM]; /* The master UDP sockets */
extern kdata *master; /* Default private key */
extern const char *tag_priv; /* Default private key tag */
*
* * "?PEER" PEER -- peer's name
*
- * * "?ERRNO" ERRNO -- system error code
+ * * "?ERR" CODE -- system error code
+ *
+ * * "?ERRNO" -- system error code from @errno@
*
* * "[!]..." ... -- @dstr_putf@-like string as single token
*/
*
* Returns: ---
*
- * Use: Creates a new admin connection.
+ * Use: Creates a new admin connection. It's safe to call this
+ * before @a_init@ -- and, indeed, this makes sense if you also
+ * call @a_switcherr@ to report initialization errors through
+ * the administration machinery.
*/
extern void a_create(int /*fd_in*/, int /*fd_out*/, unsigned /*f*/);
extern void a_daemon(void);
+/* --- @a_listen@ --- *
+ *
+ * Arguments: @const char *name@ = socket name to create
+ * @uid_t u@ = user to own the socket
+ * @gid_t g@ = group to own the socket
+ * @mode_t m@ = permissions to set on the socket
+ *
+ * Returns: ---
+ *
+ * Use: Creates the admin listening socket.
+ */
+
+extern void a_listen(const char */*sock*/,
+ uid_t /*u*/, gid_t /*g*/, mode_t /*m*/);
+
+/* --- @a_switcherr@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Arrange to report warnings, trace messages, etc. to
+ * administration clients rather than the standard-error stream.
+ *
+ * Obviously this makes no sense unless there is at least one
+ * client established. Calling @a_listen@ won't help with this,
+ * because the earliest a new client can connect is during the
+ * first select-loop iteration, which is too late: some initial
+ * client must have been added manually using @a_create@.
+ */
+
+extern void a_switcherr(void);
+
+/* --- @a_signals@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Establishes handlers for the obvious signals.
+ */
+
+extern void a_signals(void);
+
/* --- @a_init@ --- *
*
* Arguments: @const char *sock@ = socket name to create
* Use: Creates the admin listening socket.
*/
-extern void a_init(const char */*sock*/,
- uid_t /*u*/, gid_t /*g*/, mode_t /*m*/);
+extern void a_init(void);
/*----- Mapping with addresses as keys ------------------------------------*/
extern const addr *p_addr(peer */*p*/);
-/* --- @p_init@ --- *
+/* --- @p_bind@ --- *
*
* Arguments: @struct addrinfo *ailist@ = addresses to bind to
*
* Returns: ---
*
- * Use: Initializes the peer system; creates the socket.
+ * Use: Binds to the main UDP sockets.
*/
-extern void p_init(struct addrinfo */*ailist*/);
+extern void p_bind(struct addrinfo */*ailist*/);
-/* --- @p_port@ --- *
+/* --- @p_init@ --- *
+ *
+ * Arguments: ---
*
- * Arguments: @int i@ = address family index to retrieve
+ * Returns: ---
*
- * Returns: Port number used for socket.
+ * Use: Initializes the peer system.
*/
-extern unsigned p_port(int /*i*/);
+extern void p_init(void);
/* --- @p_create@ --- *
*