From 9734c97f35b35acc3e67f7188dd0e0d85a4449f1 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 24 Aug 2020 22:56:38 -0500 Subject: [PATCH] Implement src/daemon.c Implement src/daemon.c to provide a high level method to instantiate a patty server Changes: * Refactor src/server.c, src/route.c, src/if.c methods which accept callsign arguments to use a patty_ax25_addr pointer instead; this has significantly reduced the number of redundant calls to patty_ax25_pton() * Decouple patty_ax25_addr from patty_ax25_if_info types when creating new interfaces with patty_ax25_if_new(); instead, take a separate patty_ax25_addr argument * Split patty_ax25_server_run() into the following methods: - patty_ax25_server_start() - patty_ax25_server_stop() - patty_ax25_server_event_handle() This is intended to allow possible integration into other event loops. * Implement src/daemon.c to allow quick instantiation of a server, interfaces, and routes, and to encapsulate the setting of configuration variables; callsigns and interface names are handled as character strings * Rename examples/server.c to examples/daemon.c; reimplement in terms of the patty_daemon code * --- examples/Makefile | 2 +- examples/daemon.c | 84 +++++++++++++++-------- include/patty/ax25/if.h | 31 +++------ include/patty/ax25/route.h | 31 +++++---- include/patty/ax25/server.h | 35 +++++++--- include/patty/daemon.h | 35 ++++++++++ src/Makefile | 8 +-- src/daemon.c | 42 ++++++++---- src/if.c | 101 +++++++++------------------- src/route.c | 66 +++++++++++------- src/server.c | 129 +++++++++++++++++++++--------------- 11 files changed, 328 insertions(+), 236 deletions(-) create mode 100644 include/patty/daemon.h diff --git a/examples/Makefile b/examples/Makefile index e5f906c..ae8e0a4 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -7,7 +7,7 @@ INCLUDE_PATH = ../include CFLAGS += -I$(INCLUDE_PATH) LDFLAGS = -L../src -lpatty -EXAMPLES = server connect listen ax25dump decode +EXAMPLES = daemon connect listen ax25dump decode all: $(EXAMPLES) diff --git a/examples/daemon.c b/examples/daemon.c index 635f11b..f445f2a 100644 --- a/examples/daemon.c +++ b/examples/daemon.c @@ -11,6 +11,7 @@ #include #include +#include static void usage(int argc, char **argv, const char *message, ...) { if (message != NULL) { @@ -28,9 +29,7 @@ static void usage(int argc, char **argv, const char *message, ...) { } int main(int argc, char **argv) { - patty_ax25_server *server; - patty_ax25_if *iface; - patty_ax25_route *route; + patty_daemon *daemon; patty_ax25_if_kiss_tnc_info info = { .type = PATTY_AX25_IF_KISS_TNC_INFO_FD @@ -64,52 +63,85 @@ int main(int argc, char **argv) { } fprintf(stderr, "pts %s\n", pts); + } else { + struct termios t; + + memset(&t, '\0', sizeof(t)); + + t.c_cflag = CS8 | CREAD | HUPCL | CRTSCTS; + t.c_iflag = IGNPAR; + t.c_cc[VTIME] = 0; + t.c_cc[VMIN] = 1; + + cfsetspeed(&t, B9600); + + if (tcsetattr(info.fd, TCSANOW, &t) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], argv[1], "tcsetattr()", strerror(errno)); + } } errno = 0; - patty_ax25_pton(argv[3], 0, &info.addr); + if ((daemon = patty_daemon_new()) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "patty_daemon_new()", strerror(errno)); - if ((server = patty_ax25_server_new(argc >= 3? argv[2]: PATTY_AX25_SERVER_PATH)) == NULL) { - goto error_server_new; + goto error_daemon_new; } - if ((iface = patty_ax25_if_new(PATTY_AX25_IF_KISS_TNC, - (patty_ax25_if_info *)&info)) == NULL) { - goto error_if_new; + if (argc >= 3) { + if (patty_daemon_set_sock_path(daemon, argv[2]) < 0) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "patty_daemon_set_sock_path()", strerror(errno)); + + goto error_daemon_set_sock_path; + } } - if (patty_ax25_server_add_if(server, iface) < 0) { - goto error_server_add_if; + if (patty_daemon_init(daemon) < 0) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "patty_daemon_init()", strerror(errno)); + + goto error_daemon_init; } - if ((route = patty_ax25_route_new_default(iface)) == NULL) { - goto error_route_new_default; + if (patty_daemon_if_add(daemon, + PATTY_AX25_IF_KISS_TNC, + (patty_ax25_if_info *)&info, + argv[3]) < 0) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "patty_daemon_if_add()", strerror(errno)); + + goto error_daemon_if_add; } - if (patty_ax25_server_add_route(server, route) < 0) { - goto error_server_add_route; + if (patty_daemon_route_add_default(daemon, "kiss0") < 0) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "patty_daemon_route_add_default()", strerror(errno)); + + goto error_daemon_route_add_default; } - if (patty_ax25_server_run(server) < 0) { + if (patty_daemon_run(daemon) < 0) { fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], argv[1], "patty_ax25_server_run()", strerror(errno)); + argv[0], argv[1], "patty_daemon_run()", strerror(errno)); - goto error_server_run; + goto error_daemon_run; } - patty_ax25_server_destroy(server); + patty_daemon_destroy(daemon); return 0; -error_server_run: -error_server_add_route: -error_route_new_default: -error_server_add_if: -error_if_new: - patty_ax25_server_destroy(server); +error_daemon_run: +error_daemon_route_add_default: +error_daemon_if_add: +error_daemon_set_sock_path: +error_daemon_init: + patty_daemon_destroy(daemon); -error_server_new: +error_daemon_new: close(info.fd); error_open: diff --git a/include/patty/ax25/if.h b/include/patty/ax25/if.h index 757db38..57260d5 100644 --- a/include/patty/ax25/if.h +++ b/include/patty/ax25/if.h @@ -9,16 +9,10 @@ #define PATTY_AX25_IF_DEFAULT_CLASSES \ (PATTY_AX25_PARAM_CLASSES_HALF_DUPLEX) -#define PATTY_AX25_IF_OPT_TYPE_MASK 0x1f - -#define PATTY_AX25_IF_OPT_TYPE(n) \ - ((n) & PATTY_AX25_IF_OPT_TYPE_MASK) - #define PATTY_AX25_IF_DEFAULT_MTU 4096 #define PATTY_AX25_IF_DEFAULT_MRU 4096 enum patty_ax25_if_type { - PATTY_AX25_IF_UNKNOWN, PATTY_AX25_IF_KISS_TNC, PATTY_AX25_IF_HDLC }; @@ -58,40 +52,35 @@ typedef struct _patty_ax25_if { patty_dict *promisc_fds; } patty_ax25_if; -typedef struct _patty_ax25_if_info { - patty_ax25_addr addr; - unsigned int flags; -} patty_ax25_if_info; - enum patty_ax25_if_kiss_tnc_info_type { - PATTY_AX25_IF_KISS_TNC_INFO_NONE, PATTY_AX25_IF_KISS_TNC_INFO_FD, PATTY_AX25_IF_KISS_TNC_INFO_PATH }; typedef struct _patty_ax25_if_kiss_tnc_info { - patty_ax25_addr addr; - unsigned int flags; - enum patty_ax25_if_kiss_tnc_info_type type; int fd; char path[256]; } patty_ax25_if_kiss_tnc_info; -patty_ax25_if *patty_ax25_if_new(int opts, patty_ax25_if_info *info); +typedef void patty_ax25_if_info; + +patty_ax25_if *patty_ax25_if_new(enum patty_ax25_if_type type, + patty_ax25_if_info *info, + patty_ax25_addr *addr); void patty_ax25_if_destroy(patty_ax25_if *iface); int patty_ax25_if_addr_each(patty_ax25_if *iface, - int (*callback)(char *, void *), void *ctx); + int (*callback)(patty_ax25_addr *, void *), + void *ctx); -int patty_ax25_if_addr_add(patty_ax25_if *iface, const char *callsign); +int patty_ax25_if_addr_add(patty_ax25_if *iface, patty_ax25_addr *addr); -int patty_ax25_if_addr_delete(patty_ax25_if *iface, const char *callsign); +int patty_ax25_if_addr_delete(patty_ax25_if *iface, patty_ax25_addr *addr); -int patty_ax25_if_addr_match(patty_ax25_if *iface, - const patty_ax25_addr *addr); +int patty_ax25_if_addr_match(patty_ax25_if *iface, patty_ax25_addr *addr); int patty_ax25_if_promisc_add(patty_ax25_if *iface, int fd); diff --git a/include/patty/ax25/route.h b/include/patty/ax25/route.h index 5935e5a..b1d8020 100644 --- a/include/patty/ax25/route.h +++ b/include/patty/ax25/route.h @@ -2,37 +2,40 @@ #define _PATTY_AX25_ROUTE_H typedef struct _patty_ax25_route { - patty_ax25_addr dest, - hops[PATTY_AX25_MAX_HOPS]; - - size_t nhops; - patty_ax25_if *iface; + + patty_ax25_addr dest, + repeaters[PATTY_AX25_MAX_HOPS]; + + size_t hops; } patty_ax25_route; typedef struct _patty_dict patty_ax25_route_table; patty_ax25_route *patty_ax25_route_new(patty_ax25_if *iface, - const char *callsign); + patty_ax25_addr *dest, + patty_ax25_addr *repeaters, + int hops); patty_ax25_route *patty_ax25_route_new_default(patty_ax25_if *iface); -int patty_ax25_route_add_hop(patty_ax25_route *route, - const char *callsign); - patty_ax25_route_table *patty_ax25_route_table_new(); void patty_ax25_route_table_destroy(patty_ax25_route_table *table); -patty_ax25_route *patty_ax25_route_table_find(patty_ax25_route_table *table, - patty_ax25_addr *dest); - -patty_ax25_route *patty_ax25_route_table_default(patty_ax25_route_table *table); - int patty_ax25_route_table_add(patty_ax25_route_table *table, patty_ax25_route *route); int patty_ax25_route_table_delete(patty_ax25_route_table *route, patty_ax25_addr *dest); +patty_ax25_route *patty_ax25_route_table_find(patty_ax25_route_table *table, + patty_ax25_addr *dest); + +patty_ax25_route *patty_ax25_route_table_default(patty_ax25_route_table *table); + +int patty_ax25_route_table_each(patty_ax25_route_table *table, + int (*callback)(patty_ax25_route *, void *), + void *ctx); + #endif /* _PATTY_AX25_ROUTE_H */ diff --git a/include/patty/ax25/server.h b/include/patty/ax25/server.h index 92547a4..36016bb 100644 --- a/include/patty/ax25/server.h +++ b/include/patty/ax25/server.h @@ -1,31 +1,44 @@ #ifndef _PATTY_AX25_SERVER_H #define _PATTY_AX25_SERVER_H -#define PATTY_AX25_SERVER_PATH "/var/run/patty/patty.sock" -#define PATTY_AX25_SERVER_CLIENT_PATH_FORMAT "/var/run/patty/%d.sock" - typedef struct _patty_ax25_server patty_ax25_server; patty_ax25_server *patty_ax25_server_new(const char *path); void patty_ax25_server_destroy(patty_ax25_server *server); -int patty_ax25_server_add_if(patty_ax25_server *server, +int patty_ax25_server_if_add(patty_ax25_server *server, patty_ax25_if *iface); -int patty_ax25_server_delete_if(patty_ax25_server *server, - patty_ax25_if *iface); +int patty_ax25_server_if_delete(patty_ax25_server *server, + const char *ifname); -patty_ax25_if *patty_ax25_server_get_if(patty_ax25_server *server, - const char *name); +patty_ax25_if *patty_ax25_server_if_get(patty_ax25_server *server, + const char *ifname); -int patty_ax25_server_each_if(patty_ax25_server *server, +int patty_ax25_server_if_each(patty_ax25_server *server, int (*callback)(patty_ax25_if *, void *), void *ctx); -int patty_ax25_server_add_route(patty_ax25_server *server, +int patty_ax25_server_route_add(patty_ax25_server *server, patty_ax25_route *route); -int patty_ax25_server_run(patty_ax25_server *server); +int patty_ax25_server_route_delete(patty_ax25_server *server, + patty_ax25_addr *dest); + +patty_ax25_route *patty_ax25_server_route_find(patty_ax25_server *server, + patty_ax25_addr *dest); + +patty_ax25_route *patty_ax25_server_route_default(patty_ax25_server *server); + +int patty_ax25_server_route_each(patty_ax25_server *server, + int (*callback)(patty_ax25_route *, void *), + void *ctx); + +int patty_ax25_server_start(patty_ax25_server *server); + +int patty_ax25_server_stop(patty_ax25_server *server); + +int patty_ax25_server_event_handle(patty_ax25_server *server); #endif /* _PATTY_AX25_SERVER_H */ diff --git a/include/patty/daemon.h b/include/patty/daemon.h new file mode 100644 index 0000000..c42f226 --- /dev/null +++ b/include/patty/daemon.h @@ -0,0 +1,35 @@ +#ifndef _PATTY_DAEMON_H +#define _PATTY_DAEMON_H + +#define PATTY_AX25_DAEMON_SOCK_PATH "/var/run/patty/patty.sock" +#define PATTY_AX25_DAEMON_PIDFILE "/var/run/patty/patty.pid" + +typedef struct _patty_daemon patty_daemon; + +patty_daemon *patty_daemon_new(); + +void patty_daemon_destroy(patty_daemon *daemon); + +int patty_daemon_init(patty_daemon *daemon); + +int patty_daemon_run(patty_daemon *daemon); + +int patty_daemon_set_sock_path(patty_daemon *daemon, const char *path); + +int patty_daemon_set_pidfile(patty_daemon *daemon, const char *path); + +int patty_daemon_if_add(patty_daemon *daemon, + enum patty_ax25_if_type type, + patty_ax25_if_info *info, + const char *callsign); + +int patty_daemon_route_add(patty_daemon *daemon, + const char *ifname, + const char *dest, + const char **repeaters, + int hops); + +int patty_daemon_route_add_default(patty_daemon *daemon, + const char *ifname); + +#endif /* _PATTY_DAEMON_H */ diff --git a/src/Makefile b/src/Makefile index fa512e0..91e3030 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,12 +8,12 @@ CFLAGS = $(CGFLAGS) -fPIC -Wall -O2 -I$(INCLUDE_PATH) LDFLAGS = HEADERS = kiss.h ax25.h client.h ax25/if.h ax25/frame.h \ - ax25/sock.h ax25/route.h ax25/server.h list.h hash.h dict.h \ - timer.h print.h + ax25/sock.h ax25/route.h ax25/server.h daemon.h list.h \ + hash.h dict.h timer.h print.h OBJS = kiss.o ax25.o client.o if.o frame.o \ - sock.o route.o server.o list.o hash.o dict.o \ - timer.o print.o + sock.o route.o server.o daemon.o list.o \ + hash.o dict.o timer.o print.o VERSION_MAJOR = 0 VERSION_MINOR = 0.1 diff --git a/src/daemon.c b/src/daemon.c index 0e9b508..8ca4f1a 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -1,3 +1,7 @@ +#include +#include + +#include #include struct _patty_daemon { @@ -14,6 +18,8 @@ patty_daemon *patty_daemon_new() { goto error_malloc; } + memset(daemon, '\0', sizeof(*daemon)); + if (patty_daemon_set_sock_path(daemon, PATTY_AX25_DAEMON_SOCK_PATH) < 0) { goto error_set_sock_path; } @@ -36,6 +42,8 @@ error_malloc: void patty_daemon_destroy(patty_daemon *daemon) { patty_ax25_server_destroy(daemon->server); + + free(daemon); } int patty_daemon_init(patty_daemon *daemon) { @@ -65,6 +73,9 @@ int patty_daemon_run(patty_daemon *daemon) { return 0; error_server_event_handle: + patty_ax25_server_stop(daemon->server); + +error_server_start: return -1; } @@ -98,26 +109,33 @@ error_strdup: return -1; } -int patty_ax25_daemon_if_add(patty_ax25_daemon *daemon, - int opts, - patty_ax25_if_info *info) { +int patty_daemon_if_add(patty_daemon *daemon, + enum patty_ax25_if_type type, + patty_ax25_if_info *info, + const char *callsign) { patty_ax25_if *iface; + patty_ax25_addr addr; - if ((iface = patty_ax25_if_new(opts, info)) == NULL) { + if (patty_ax25_pton(callsign, &addr) < 0) { + goto error_pton; + } + + if ((iface = patty_ax25_if_new(type, info, &addr)) == NULL) { goto error_if_new; } - return patty_ax25_server_add_if(daemon->server, iface); + return patty_ax25_server_if_add(daemon->server, iface); error_if_new: +error_pton: return -1; } -int patty_ax25_daemon_route_add(patty_ax25_daemon *daemon, - const char *ifname, - const char *dest, - const char **repeaters, - int hops) { +int patty_daemon_route_add(patty_daemon *daemon, + const char *ifname, + const char *dest, + const char **repeaters, + int hops) { patty_ax25_route *route; patty_ax25_if *iface; @@ -131,7 +149,7 @@ int patty_ax25_daemon_route_add(patty_ax25_daemon *daemon, goto error_malloc_route; } - memset(&route, '\0', sizeof(route)); + memset(route, '\0', sizeof(*route)); route->iface = iface; @@ -157,7 +175,7 @@ error_server_if_get: return -1; } -int patty_daemon_route_add_default(patty_ax25_daemon *daemon, +int patty_daemon_route_add_default(patty_daemon *daemon, const char *ifname) { return patty_daemon_route_add(daemon, ifname, NULL, NULL, 0); } diff --git a/src/if.c b/src/if.c index c8420e5..54c8908 100644 --- a/src/if.c +++ b/src/if.c @@ -33,7 +33,9 @@ static void destroy_tnc(patty_ax25_if *iface) { patty_kiss_tnc_destroy(iface->tnc); } -patty_ax25_if *patty_ax25_if_new(int opts, patty_ax25_if_info *info) { +patty_ax25_if *patty_ax25_if_new(enum patty_ax25_if_type type, + patty_ax25_if_info *info, + patty_ax25_addr *addr) { patty_ax25_if *iface; if ((iface = malloc(sizeof(*iface))) == NULL) { @@ -42,7 +44,7 @@ patty_ax25_if *patty_ax25_if_new(int opts, patty_ax25_if_info *info) { memset(iface, '\0', sizeof(*iface)); - if (info->addr.callsign[0] == '\0') { + if (addr->callsign[0] == '\0') { errno = EINVAL; goto error_invalid_address; @@ -74,7 +76,7 @@ patty_ax25_if *patty_ax25_if_new(int opts, patty_ax25_if_info *info) { goto error_dict_new_promisc_fds; } - switch (PATTY_AX25_IF_OPT_TYPE(opts)) { + switch (type) { case PATTY_AX25_IF_KISS_TNC: if (init_tnc(iface, (patty_ax25_if_kiss_tnc_info *)info) < 0) { goto error_init; @@ -83,12 +85,12 @@ patty_ax25_if *patty_ax25_if_new(int opts, patty_ax25_if_info *info) { break; default: - errno = EINVAL; + errno = ENOSYS; goto error_invalid_if_type; } - memcpy(&iface->addr, &info->addr, sizeof(iface->addr)); + memcpy(&iface->addr, addr, sizeof(iface->addr)); return iface; @@ -132,27 +134,18 @@ void patty_ax25_if_destroy(patty_ax25_if *iface) { } int patty_ax25_if_addr_each(patty_ax25_if *iface, - int (*callback)(char *, void *), void *ctx) { + int (*callback)(patty_ax25_addr *, void *), + void *ctx) { patty_list_item *item = iface->aliases->first; - char buf[PATTY_AX25_ADDRESS_LEN+1]; - - if (patty_ax25_ntop(&iface->addr, buf, sizeof(buf)) < 0) { - goto error_ntop_addr; - } - - if (callback(buf, ctx) < 0) { - goto error_callback_addr; + if (callback(&iface->addr, ctx) < 0) { + goto error_callback; } while (item) { patty_ax25_addr *addr = item->value; - if (patty_ax25_ntop(addr, buf, sizeof(buf)) < 0) { - goto error_ntop; - } - - if (callback(buf, ctx) < 0) { + if (callback(addr, ctx) < 0) { goto error_callback; } @@ -162,97 +155,70 @@ int patty_ax25_if_addr_each(patty_ax25_if *iface, return 0; error_callback: -error_ntop: -error_callback_addr: -error_ntop_addr: return -1; } static patty_ax25_addr *find_addr(patty_ax25_if *iface, - const char *callsign) { + patty_ax25_addr *addr) { patty_list_item *item = iface->aliases->first; - char buf[PATTY_AX25_ADDRESS_LEN+1]; - - if (patty_ax25_ntop(&iface->addr, buf, sizeof(buf)) < 0) { - goto error_ntop_addr; - } - - if (strncmp(buf, callsign, sizeof(buf)) == 0) { - return &iface->addr; - } - while (item) { - patty_ax25_addr *addr = item->value; + patty_ax25_addr *cur = item->value; - if (patty_ax25_ntop(addr, buf, sizeof(buf)) < 0) { - goto error_ntop; + if (memcpy(&addr->callsign, + &cur->callsign, + sizeof(addr->callsign)) == 0) { + return addr; } - if (strncmp(buf, callsign, sizeof(buf)) != 0) { - goto next; - } - - return addr; -next: item = item->next; } -error_ntop: -error_ntop_addr: return NULL; } int patty_ax25_if_addr_add(patty_ax25_if *iface, - const char *callsign) { - patty_ax25_addr *addr; + patty_ax25_addr *addr) { + patty_ax25_addr *alias; - if (find_addr(iface, callsign) != NULL) { + if (find_addr(iface, addr) != NULL) { errno = EADDRINUSE; goto error_exists; } - if ((addr = malloc(sizeof(*addr))) == NULL) { - goto error_malloc_addr; + if ((alias = malloc(sizeof(*alias))) == NULL) { + goto error_malloc_alias; } - if (patty_ax25_pton(callsign, addr) < 0) { - goto error_pton; - } + memcpy(&alias->callsign, &addr->callsign, sizeof(alias->callsign)); addr->ssid = 0; - if ((patty_list_append(iface->aliases, addr)) == NULL) { + if ((patty_list_append(iface->aliases, alias)) == NULL) { goto error_list_append; } return 0; error_list_append: -error_pton: - free(addr); + free(alias); -error_malloc_addr: +error_malloc_alias: error_exists: return -1; } -int patty_ax25_if_addr_delete(patty_ax25_if *iface, - const char *callsign) { +int patty_ax25_if_addr_delete(patty_ax25_if *iface, patty_ax25_addr *addr) { patty_list_item *item = iface->aliases->first; int i = 0; while (item) { - char buf[PATTY_AX25_ADDRESS_LEN+1]; + patty_ax25_addr *alias = item->value; - patty_ax25_addr *addr = item->value; - - if (patty_ax25_ntop(addr, buf, sizeof(buf)) < 0) { - goto error_ntop; - } - - if (strncmp(buf, callsign, sizeof(buf)) == 0) { + if (memcmp(&addr->callsign, + &alias->callsign, + sizeof(addr->callsign)) == 0) { if (patty_list_splice(iface->aliases, i) == NULL) { goto error_list_splice; } @@ -265,12 +231,11 @@ int patty_ax25_if_addr_delete(patty_ax25_if *iface, return 0; error_list_splice: -error_ntop: return -1; } int patty_ax25_if_addr_match(patty_ax25_if *iface, - const patty_ax25_addr *addr) { + patty_ax25_addr *addr) { patty_list_item *item; if (memcmp(&iface->addr.callsign, diff --git a/src/route.c b/src/route.c index d405aff..d232d3c 100644 --- a/src/route.c +++ b/src/route.c @@ -8,50 +8,46 @@ #include patty_ax25_route *patty_ax25_route_new(patty_ax25_if *iface, - const char *callsign) { + patty_ax25_addr *dest, + patty_ax25_addr *repeaters, + int hops) { patty_ax25_route *route; + int i; + + if (hops >= PATTY_AX25_MAX_HOPS) { + errno = EOVERFLOW; + + goto error_max_hops; + } + if ((route = malloc(sizeof(*route))) == NULL) { goto error_malloc_route; } memset(route, '\0', sizeof(*route)); - if (callsign) { - if (patty_ax25_pton(callsign, &route->dest) < 0) { - goto error_pton; - } + route->iface = iface; + + if (dest) { + patty_ax25_addr_copy(&route->dest, dest, 0); } - route->iface = iface; + for (i=0; irepeaters, &repeaters[i], 0); + } return route; -error_pton: - free(route); - error_malloc_route: +error_max_hops: return NULL; } patty_ax25_route *patty_ax25_route_new_default(patty_ax25_if *iface) { - return patty_ax25_route_new(iface, NULL); + return patty_ax25_route_new(iface, NULL, NULL, 0); } -int patty_ax25_route_add_hop(patty_ax25_route *route, - const char *callsign) { - if (route->nhops == PATTY_AX25_MAX_HOPS) { - errno = ENOMEM; - - goto error_max_hops; - } - - return patty_ax25_pton(callsign, &route->hops[route->nhops++]); - -error_max_hops: - return -1; -} - patty_ax25_route_table *patty_ax25_route_table_new() { return patty_dict_new(); } @@ -92,6 +88,28 @@ patty_ax25_route *patty_ax25_route_table_default(patty_ax25_route_table *table) return patty_dict_get(table, hash); } +struct dict_ctx_wrapper { + int (*callback)(patty_ax25_route *route, void *); + void *ctx; +}; + +static int each_dict_callback(uint32_t key, void *value, void *ctx) { + struct dict_ctx_wrapper *wrapper = ctx; + + return wrapper->callback(value, wrapper->ctx); +} + +int patty_ax25_route_table_each(patty_ax25_route_table *table, + int (*callback)(patty_ax25_route *, void *), + void *ctx) { + struct dict_ctx_wrapper wrapper = { + .callback = callback, + .ctx = ctx + }; + + return patty_dict_each(table, each_dict_callback, &wrapper); +} + int patty_ax25_route_table_add(patty_ax25_route_table *table, patty_ax25_route *route) { uint32_t hash; diff --git a/src/server.c b/src/server.c index 2c9c0db..52a5d17 100644 --- a/src/server.c +++ b/src/server.c @@ -132,7 +132,7 @@ void patty_ax25_server_destroy(patty_ax25_server *server) { patty_dict_destroy(server->socks_by_client); patty_dict_destroy(server->socks_by_fd); - patty_ax25_server_each_if(server, destroy_if, NULL); + patty_ax25_server_if_each(server, destroy_if, NULL); patty_ax25_route_table_destroy(server->routes); patty_list_destroy(server->ifaces); @@ -432,7 +432,7 @@ static inline void sock_flow_start(patty_ax25_server *server, fd_watch(server, sock->fd); } -int patty_ax25_server_add_if(patty_ax25_server *server, +int patty_ax25_server_if_add(patty_ax25_server *server, patty_ax25_if *iface) { int fd; @@ -450,14 +450,20 @@ error_list_append: return -1; } -int patty_ax25_server_delete_if(patty_ax25_server *server, - patty_ax25_if *iface) { +int patty_ax25_server_if_delete(patty_ax25_server *server, + const char *ifname) { patty_list_item *item = server->ifaces->first; int fd, i = 0; while (item) { - if (item->value == iface) { + patty_ax25_if *iface = item->value; + + if (strncmp(iface->name, ifname, sizeof(iface->name)) == 0) { + if ((fd = patty_kiss_tnc_fd(iface->tnc)) >= 0) { + fd_clear(server, fd); + } + if (patty_list_splice(server->ifaces, i) == NULL) { goto error_list_splice; } @@ -469,17 +475,13 @@ int patty_ax25_server_delete_if(patty_ax25_server *server, i++; } - if ((fd = patty_kiss_tnc_fd(iface->tnc)) >= 0) { - fd_clear(server, fd); - } - return 0; error_list_splice: return -1; } -patty_ax25_if *patty_ax25_server_get_if(patty_ax25_server *server, +patty_ax25_if *patty_ax25_server_if_get(patty_ax25_server *server, const char *name) { patty_list_item *item = server->ifaces->first; @@ -496,7 +498,7 @@ patty_ax25_if *patty_ax25_server_get_if(patty_ax25_server *server, return NULL; } -int patty_ax25_server_each_if(patty_ax25_server *server, +int patty_ax25_server_if_each(patty_ax25_server *server, int (*callback)(patty_ax25_if *, void *), void *ctx) { patty_list_item *item = server->ifaces->first; @@ -517,11 +519,31 @@ error_callback: return -1; } -int patty_ax25_server_add_route(patty_ax25_server *server, +int patty_ax25_server_route_add(patty_ax25_server *server, patty_ax25_route *route) { return patty_ax25_route_table_add(server->routes, route); } +int patty_ax25_server_route_delete(patty_ax25_server *server, + patty_ax25_addr *dest) { + return patty_ax25_route_table_delete(server->routes, dest); +} + +patty_ax25_route *patty_ax25_server_route_find(patty_ax25_server *server, + patty_ax25_addr *dest) { + return patty_ax25_route_table_find(server->routes, dest); +} + +patty_ax25_route *patty_ax25_server_route_default(patty_ax25_server *server) { + return patty_ax25_route_table_default(server->routes); +} + +int patty_ax25_server_route_each(patty_ax25_server *server, + int (*callback)(patty_ax25_route *, void *), + void *ctx) { + return patty_ax25_route_table_each(server->routes, callback, ctx); +} + static int respond_accept(int client, int ret, int eno) { @@ -665,7 +687,7 @@ static int server_setsockopt(patty_ax25_server *server, goto error_read; } - if ((iface = patty_ax25_server_get_if(server, data.name)) == NULL) { + if ((iface = patty_ax25_server_if_get(server, data.name)) == NULL) { response.ret = -1; response.eno = ENODEV; @@ -2274,66 +2296,63 @@ static int handle_socks(patty_ax25_server *server) { return patty_dict_each(server->socks_by_fd, handle_sock, server); } -int patty_ax25_server_run(patty_ax25_server *server) { - if (listen_unix(server, server->path) < 0) { - goto error_listen_unix; +int patty_ax25_server_start(patty_ax25_server *server) { + return listen_unix(server, server->path); +} + +int patty_ax25_server_stop(patty_ax25_server *server) { + return close(server->fd); +} + +int patty_ax25_server_event_handle(patty_ax25_server *server) { + int nready; + + struct timeval timeout = { 1, 0 }; + + struct timespec before, + after; + + memcpy(&server->fds_r, &server->fds_watch, sizeof(server->fds_r)); + + if (clock_gettime(CLOCK_MONOTONIC, &before) < 0) { + goto error_clock_gettime; } - while (1) { - int nready; + if ((nready = select( server->fd_max, + &server->fds_r, + NULL, + NULL, + &timeout)) < 0) { + goto error_io; + } - struct timeval timeout = { 1, 0 }; + if (clock_gettime(CLOCK_MONOTONIC, &after) < 0) { + goto error_clock_gettime; + } - struct timespec before, - after; + patty_timer_sub(&after, &before, &server->elapsed); - memcpy(&server->fds_r, &server->fds_watch, sizeof(server->fds_r)); + if (handle_socks(server) < 0) { + goto error_io; + } - if (clock_gettime(CLOCK_MONOTONIC, &before) < 0) { - goto error_clock_gettime; - } - - if ((nready = select( server->fd_max, - &server->fds_r, - NULL, - NULL, - &timeout)) < 0) { + if (nready > 0) { + if (handle_clients(server) < 0) { goto error_io; } - if (clock_gettime(CLOCK_MONOTONIC, &after) < 0) { - goto error_clock_gettime; - } - - patty_timer_sub(&after, &before, &server->elapsed); - - if (handle_socks(server) < 0) { + if (handle_ifaces(server) < 0) { goto error_io; } - if (nready > 0) { - if (handle_clients(server) < 0) { - goto error_io; - } - - if (handle_ifaces(server) < 0) { - goto error_io; - } - - if (accept_client(server) < 0) { - goto error_io; - } + if (accept_client(server) < 0) { + goto error_io; } } - close(server->fd); - return 0; error_clock_gettime: error_io: - close(server->fd); - -error_listen_unix: return -1; }