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

    *
This commit is contained in:
XANTRONIX Development 2020-08-24 22:56:38 -05:00 committed by XANTRONIX Industrial
parent 0fecccd7c3
commit 9734c97f35
11 changed files with 328 additions and 236 deletions

View file

@ -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)

View file

@ -11,6 +11,7 @@
#include <errno.h>
#include <patty/ax25.h>
#include <patty/daemon.h>
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:

View file

@ -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);

View file

@ -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 */

View file

@ -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 */

35
include/patty/daemon.h Normal file
View file

@ -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 */

View file

@ -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

View file

@ -1,3 +1,7 @@
#include <stdlib.h>
#include <string.h>
#include <patty/ax25.h>
#include <patty/daemon.h>
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);
}

101
src/if.c
View file

@ -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,

View file

@ -8,50 +8,46 @@
#include <patty/ax25.h>
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; i<hops; i++) {
patty_ax25_addr_copy(&route->repeaters, &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;

View file

@ -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;
}