Support multiple listening ports per listener type.

Beast input defaults to listening on both 30004 and 30104.
Drop the FATSV listener entirely (use faup1090 for that)
Ignore --net-beast.
This commit is contained in:
Oliver Jowett 2016-01-24 18:45:35 +00:00
parent 1a2926b311
commit 2b466535de
11 changed files with 124 additions and 120 deletions

View file

@ -84,9 +84,6 @@ BEAST_INPUT_PORT=
# Port to listen on for Beast-format output connections. 0 disables.
BEAST_OUTPUT_PORT=
# Port to listen on for FATSV-format output connections. 0 disables.
FATSV_OUTPUT_PORT=
# TCP heartbeat interval in seconds. 0 disables.
NET_HEARTBEAT=

View file

@ -38,7 +38,6 @@ if [ -e $CONFIGFILE ]; then
db_set $NAME/net-bi-port "$BEAST_INPUT_PORT"
db_set $NAME/net-bo-port "$BEAST_OUTPUT_PORT"
db_set $NAME/net-sbs-port "$SBS_OUTPUT_PORT"
db_set $NAME/net-fatsv-port "$FATSV_OUTPUT_PORT"
db_set $NAME/net-heartbeat "$NET_HEARTBEAT"
db_set $NAME/net-out-size "$NET_OUTPUT_SIZE"
db_set $NAME/net-out-interval "$NET_OUTPUT_INTERVAL"
@ -183,6 +182,13 @@ is_port_number() {
fi
}
is_port_list() {
for port in $(echo $1 | sed 's@,@ @g'); do
if ! is_port_number "$port"; then return 0; fi
done
return 1
}
db_input high $NAME/auto-start || true
db_input_verify low $NAME/run-as-user is_non_root_user || true
db_input_verify low $NAME/log-file is_not_empty || true
@ -208,13 +214,12 @@ db_go || true; db_get $NAME/auto-start; if [ "$RET" = "true" ]; then
db_input_verify medium $NAME/decode-lon is_number_or_empty || true
fi
db_input_verify medium $NAME/net-http-port is_port_number || true
db_input_verify low $NAME/net-ri-port is_port_number || true
db_input_verify low $NAME/net-ro-port is_port_number || true
db_input_verify low $NAME/net-bi-port is_port_number || true
db_input_verify low $NAME/net-bo-port is_port_number || true
db_input_verify low $NAME/net-sbs-port is_port_number || true
db_input_verify low $NAME/net-fatsv-port is_port_number || true
db_input_verify medium $NAME/net-http-port is_port_list || true
db_input_verify low $NAME/net-ri-port is_port_list || true
db_input_verify low $NAME/net-ro-port is_port_list || true
db_input_verify low $NAME/net-bi-port is_port_list || true
db_input_verify low $NAME/net-bo-port is_port_list || true
db_input_verify low $NAME/net-sbs-port is_port_list || true
db_input_verify low $NAME/net-heartbeat is_unsigned_number || true
db_input_verify low $NAME/net-out-size is_unsigned_int || true
db_input_verify low $NAME/net-out-interval is_unsigned_number || true

View file

@ -39,7 +39,6 @@ SCRIPTNAME=/etc/init.d/$NAME
[ -z "$SBS_OUTPUT_PORT" ] && SBS_OUTPUT_PORT=0
[ -z "$BEAST_INPUT_PORT" ] && BEAST_INPUT_PORT=0
[ -z "$BEAST_OUTPUT_PORT" ] && BEAST_OUTPUT_PORT=0
[ -z "$FATSV_OUTPUT_PORT" ] && FATSV_OUTPUT_PORT=0
[ -z "$NET_BUFFER" ] && NET_BUFFER=0
[ -z "$JSON_INTERVAL" ] && JSON_INTERVAL=0
[ -z "$MAX_RANGE" ] && MAX_RANGE=300
@ -72,7 +71,7 @@ ARGS="$ARGS --max-range $MAX_RANGE"; fi
ARGS="$ARGS --net-http-port $HTTP_PORT \
--net-ri-port $RAW_INPUT_PORT --net-ro-port $RAW_OUTPUT_PORT \
--net-bi-port $BEAST_INPUT_PORT --net-bo-port $BEAST_OUTPUT_PORT \
--net-sbs-port $SBS_OUTPUT_PORT --net-fatsv-port $FATSV_OUTPUT_PORT"
--net-sbs-port $SBS_OUTPUT_PORT"
if [ -n "$NET_HEARTBEAT" ]; then ARGS="$ARGS --net-heartbeat $NET_HEARTBEAT"; fi
if [ -n "$NET_OUTPUT_SIZE" ]; then ARGS="$ARGS --net-ro-size $NET_OUTPUT_SIZE"; fi
if [ -n "$NET_OUTPUT_INTERVAL" ]; then ARGS="$ARGS --net-ro-interval $NET_OUTPUT_INTERVAL"; fi

View file

@ -131,7 +131,7 @@ Type: string
Default: 0
Template: dump1090-mutability/net-ri-port
Description: Port for AVR-format input connections (0 disables):
Description: Portsfor AVR-format input connections (0 disables):
dump1090 can accept connections to receive data from other sources in
several formats. This setting controls the port dump1090 will listen
on for AVR ("raw") format input connections.
@ -139,7 +139,7 @@ Type: string
Default: 30001
Template: dump1090-mutability/net-ro-port
Description: Port for AVR-format output connections (0 disables):
Description: Ports for AVR-format output connections (0 disables):
dump1090 can forward ADS-B messages to other software in several formats.
This setting controls the port dump1090 will listen on for AVR ("raw")
format output connections.
@ -147,15 +147,15 @@ Type: string
Default: 30002
Template: dump1090-mutability/net-bi-port
Description: Port for Beast-format input connections (0 disables):
Description: Ports for Beast-format input connections (0 disables):
dump1090 can accept connections to receive data from other sources in
several formats. This setting controls the port dump1090 will listen
on for Beast ("binary") format input connections.
Type: string
Default: 30004
Default: 30004,30104
Template: dump1090-mutability/net-bo-port
Description: Port for Beast-format output connections (0 disables):
Description: Ports for Beast-format output connections (0 disables):
dump1090 can forward ADS-B messages to other software in several formats.
This setting controls the port dump1090 will listen on for Beast ("binary")
format output connections.
@ -163,21 +163,13 @@ Type: string
Default: 30005
Template: dump1090-mutability/net-sbs-port
Description: Port for SBS-format output connections (0 disables):
Description: Ports for SBS-format output connections (0 disables):
dump1090 can forward ADS-B messages to other software in several formats.
This setting controls the port dump1090 will listen on for SBS BaseStation
format output connections.
Type: string
Default: 30003
Template: dump1090-mutability/net-fatsv-port
Description: Port for FATSV-format output connections (0 disables):
dump1090 can forward ADS-B messages to other software in several formats.
This setting controls the port dump1090 will listen on for FlightAware TSV
format output connections.
Type: string
Default: 10001
Template: dump1090-mutability/net-heartbeat
Description: Seconds between heartbeat messages (0 disables):
If there is no other data sent on a network connection, dump1090 can
@ -313,6 +305,10 @@ Template: dump1090-mutability/invalid-is_port_number
Description: Value must be a valid port number (1024-65535), or zero to disable.
Type: error
Template: dump1090-mutability/invalid-is_port_list
Description: Value must be a comma-separated list of valid port numbers (1024-65535), or zero to disable.
Type: error
Template: dump1090-mutability/invalid-is_ipaddrish_or_empty
Description: Value must be an IP address or empty.
Type: error

View file

@ -145,13 +145,12 @@ void modesInitConfig(void) {
Modes.ppm_error = MODES_DEFAULT_PPM;
Modes.check_crc = 1;
Modes.net_heartbeat_interval = MODES_NET_HEARTBEAT_INTERVAL;
Modes.net_output_sbs_port = MODES_NET_OUTPUT_SBS_PORT;
Modes.net_output_raw_port = MODES_NET_OUTPUT_RAW_PORT;
Modes.net_input_raw_port = MODES_NET_INPUT_RAW_PORT;
Modes.net_output_beast_port = MODES_NET_OUTPUT_BEAST_PORT;
Modes.net_input_beast_port = MODES_NET_INPUT_BEAST_PORT;
Modes.net_http_port = MODES_NET_HTTP_PORT;
Modes.net_fatsv_port = MODES_NET_OUTPUT_FA_TSV_PORT;
Modes.net_output_raw_ports = strdup("30001");
Modes.net_input_raw_ports = strdup("30002");
Modes.net_output_sbs_ports = strdup("30003");
Modes.net_input_beast_ports = strdup("30004,30104");
Modes.net_output_beast_ports = strdup("30005");
Modes.net_http_ports = strdup("8080");
Modes.interactive_rows = getTermRows();
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
Modes.html_dir = HTMLPATH;
@ -682,13 +681,12 @@ void showHelp(void) {
"--modeac Enable decoding of SSR Modes 3/A & 3/C\n"
"--net-only Enable just networking, no RTL device or file used\n"
"--net-bind-address <ip> IP address to bind to (default: Any; Use 127.0.0.1 for private)\n"
"--net-http-port <port> HTTP server port (default: 8080)\n"
"--net-ri-port <port> TCP raw input listen port (default: 30001)\n"
"--net-ro-port <port> TCP raw output listen port (default: 30002)\n"
"--net-sbs-port <port> TCP BaseStation output listen port (default: 30003)\n"
"--net-bi-port <port> TCP Beast input listen port (default: 30004)\n"
"--net-bo-port <port> TCP Beast output listen port (default: 30005)\n"
"--net-fatsv-port <port> FlightAware TSV output port (default: 10001)\n"
"--net-http-port <ports> HTTP server ports (default: 8080)\n"
"--net-ri-port <ports> TCP raw input listen ports (default: 30001)\n"
"--net-ro-port <ports> TCP raw output listen ports (default: 30002)\n"
"--net-sbs-port <ports> TCP BaseStation output listen ports (default: 30003)\n"
"--net-bi-port <ports> TCP Beast input listen ports (default: 30004,30104)\n"
"--net-bo-port <ports> TCP Beast output listen ports (default: 30005)\n"
"--net-ro-size <size> TCP output minimum size (default: 0)\n"
"--net-ro-interval <rate> TCP output memory flush rate in seconds (default: 0)\n"
"--net-heartbeat <rate> TCP heartbeat rate in seconds (default: 60 sec; 0 to disable)\n"
@ -825,8 +823,8 @@ void backgroundTasks(void) {
next_json = now + Modes.json_interval;
}
if ((Modes.json_dir || Modes.net_http_port) && now >= next_history) {
int rewrite_receiver_json = (Modes.json_aircraft_history[HISTORY_SIZE-1].content == NULL);
if (now >= next_history) {
int rewrite_receiver_json = (Modes.json_dir && Modes.json_aircraft_history[HISTORY_SIZE-1].content == NULL);
free(Modes.json_aircraft_history[Modes.json_aircraft_history_next].content); // might be NULL, that's OK.
Modes.json_aircraft_history[Modes.json_aircraft_history_next].content =
@ -968,7 +966,7 @@ int main(int argc, char **argv) {
} else if (!strcmp(argv[j],"--modeac")) {
Modes.mode_ac = 1;
} else if (!strcmp(argv[j],"--net-beast")) {
Modes.beast = 1;
fprintf(stderr, "--net-beast ignored, use --net-bo-port to control where Beast output is generated\n");
} else if (!strcmp(argv[j],"--net-only")) {
Modes.net = 1;
Modes.net_only = 1;
@ -981,24 +979,26 @@ int main(int argc, char **argv) {
} else if (!strcmp(argv[j],"--net-ro-interval") && more) {
Modes.net_output_flush_interval = (uint64_t)(1000 * atof(argv[++j]));
} else if (!strcmp(argv[j],"--net-ro-port") && more) {
if (Modes.beast) // Required for legacy backward compatibility
{Modes.net_output_beast_port = atoi(argv[++j]);;}
else
{Modes.net_output_raw_port = atoi(argv[++j]);}
free(Modes.net_output_raw_ports);
Modes.net_output_raw_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-ri-port") && more) {
Modes.net_input_raw_port = atoi(argv[++j]);
free(Modes.net_input_raw_ports);
Modes.net_input_raw_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-bo-port") && more) {
Modes.net_output_beast_port = atoi(argv[++j]);
free(Modes.net_output_beast_ports);
Modes.net_output_beast_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-bi-port") && more) {
Modes.net_input_beast_port = atoi(argv[++j]);
free(Modes.net_input_beast_ports);
Modes.net_input_beast_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-bind-address") && more) {
free(Modes.net_bind_address);
Modes.net_bind_address = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-http-port") && more) {
Modes.net_http_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-fatsv-port") && more) {
Modes.net_fatsv_port = atoi(argv[++j]);
free(Modes.net_http_ports);
Modes.net_http_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-sbs-port") && more) {
Modes.net_output_sbs_port = atoi(argv[++j]);
free(Modes.net_output_sbs_ports);
Modes.net_output_sbs_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-buffer") && more) {
Modes.net_sndbuf_size = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-verbatim")) {

View file

@ -191,14 +191,6 @@ typedef struct rtlsdr_dev rtlsdr_dev_t;
#define MODES_NET_HEARTBEAT_INTERVAL 60000 // milliseconds
#define MODES_NET_SERVICES_NUM 7
#define MODES_NET_INPUT_RAW_PORT 30001
#define MODES_NET_OUTPUT_RAW_PORT 30002
#define MODES_NET_OUTPUT_SBS_PORT 30003
#define MODES_NET_INPUT_BEAST_PORT 30004
#define MODES_NET_OUTPUT_BEAST_PORT 30005
#define MODES_NET_HTTP_PORT 8080
#define MODES_NET_OUTPUT_FA_TSV_PORT 10001
#define MODES_CLIENT_BUF_SIZE 1024
#define MODES_NET_SNDBUF_SIZE (1024*64)
#define MODES_NET_SNDBUF_MAX (7)
@ -296,22 +288,20 @@ struct { // Internal state
int nfix_crc; // Number of crc bit error(s) to correct
int check_crc; // Only display messages with good CRC
int raw; // Raw output format
int beast; // Beast binary format output
int mode_ac; // Enable decoding of SSR Modes A & C
int debug; // Debugging mode
int net; // Enable networking
int net_only; // Enable just networking
uint64_t net_heartbeat_interval; // TCP heartbeat interval (milliseconds)
int net_output_sbs_port; // SBS output TCP port
int net_output_flush_size; // Minimum Size of output data
uint64_t net_output_flush_interval; // Maximum interval (in milliseconds) between outputwrites
int net_output_raw_port; // Raw output TCP port
int net_input_raw_port; // Raw input TCP port
int net_output_beast_port; // Beast output TCP port
int net_input_beast_port; // Beast input TCP port
char *net_bind_address; // Bind address
int net_http_port; // HTTP port
int net_fatsv_port; // FlightAware TSV port
char *net_output_raw_ports; // List of raw output TCP ports
char *net_input_raw_ports; // List of raw input TCP ports
char *net_output_sbs_ports; // List of SBS output TCP ports
char *net_input_beast_ports; // List of Beast input TCP ports
char *net_output_beast_ports; // List of Beast output TCP ports
char *net_http_ports; // List of HTTP ports
char *net_bind_address; // Bind address
int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n)
int net_verbatim; // if true, send the original message, not the CRC-corrected one
int forward_mlat; // allow forwarding of mlat messages to output ports

View file

@ -139,7 +139,7 @@ int main(int argc, char **argv) {
int j;
int stdout_option = 0;
char *bo_connect_ipaddr = "127.0.0.1";
int bo_connect_port = MODES_NET_OUTPUT_BEAST_PORT;
int bo_connect_port = 30005;
struct client *c;
struct net_service *beast_input, *fatsv_output;

102
net_io.c
View file

@ -96,7 +96,7 @@ struct net_service *serviceInit(const char *descr, struct net_writer *writer, he
Modes.services = service;
service->descr = descr;
service->listen_fd = -1;
service->listener_count = 0;
service->connections = 0;
service->writer = writer;
service->read_sep = sep;
@ -163,24 +163,57 @@ struct client *serviceConnect(struct net_service *service, char *addr, int port)
// Set up the given service to listen on an address/port.
// _exits_ on failure!
void serviceListen(struct net_service *service, char *bind_addr, int bind_port)
void serviceListen(struct net_service *service, char *bind_addr, char *bind_ports)
{
int s;
int *fds = NULL;
int n = 0;
char *p, *end;
if (service->listen_fd >= 0) {
if (service->listener_count > 0) {
fprintf(stderr, "Tried to set up the service %s twice!\n", service->descr);
exit(1);
}
s = anetTcpServer(Modes.aneterr, bind_port, bind_addr);
if (s == ANET_ERR) {
fprintf(stderr, "Error opening the listening port %d (%s): %s\n",
bind_port, service->descr, Modes.aneterr);
exit(1);
if (!bind_ports || !strcmp(bind_ports, "") || !strcmp(bind_ports, "0"))
return;
p = bind_ports;
while (*p) {
int s;
unsigned long port = strtoul(p, &end, 10);
if (p == end) {
fprintf(stderr,
"Couldn't parse port list: %s\n"
" %*s^\n",
bind_ports, (int)(p - bind_ports), "");
exit(1);
}
s = anetTcpServer(Modes.aneterr, port, bind_addr);
if (s == ANET_ERR) {
fprintf(stderr, "Error opening the listening port %lu (%s): %s\n",
port, service->descr, Modes.aneterr);
exit(1);
}
anetNonBlock(Modes.aneterr, s);
fds = realloc(fds, (n+1) * sizeof(int));
if (!fds) {
fprintf(stderr, "out of memory\n");
exit(1);
}
fds[n] = s;
++n;
p = end;
if (*p == ',')
++p;
}
anetNonBlock(Modes.aneterr, s);
service->listen_fd = s;
service->listener_count = n;
service->listener_fds = fds;
}
struct net_service *makeBeastInputService(void)
@ -201,41 +234,23 @@ void modesInitNet(void) {
Modes.services = NULL;
// set up listeners
s = serviceInit("Raw TCP output", &Modes.raw_out, send_raw_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_raw_ports);
if (Modes.net_output_raw_port) {
s = serviceInit("Raw TCP output", &Modes.raw_out, send_raw_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_raw_port);
}
s = serviceInit("Beast TCP output", &Modes.beast_out, send_beast_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_beast_ports);
if (Modes.net_output_beast_port) {
s = serviceInit("Beast TCP output", &Modes.beast_out, send_beast_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_beast_port);
}
s = serviceInit("Basestation TCP output", &Modes.sbs_out, send_sbs_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_sbs_ports);
if (Modes.net_output_sbs_port) {
s = serviceInit("Basestation TCP output", &Modes.sbs_out, send_sbs_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_sbs_port);
}
s = serviceInit("Raw TCP input", NULL, NULL, "\n", decodeHexMessage);
serviceListen(s, Modes.net_bind_address, Modes.net_input_raw_ports);
if (Modes.net_fatsv_port) {
s = makeFatsvOutputService();
serviceListen(s, Modes.net_bind_address, Modes.net_fatsv_port);
}
s = makeBeastInputService();
serviceListen(s, Modes.net_bind_address, Modes.net_input_beast_ports);
if (Modes.net_input_raw_port) {
s = serviceInit("Raw TCP input", NULL, NULL, "\n", decodeHexMessage);
serviceListen(s, Modes.net_bind_address, Modes.net_input_raw_port);
}
if (Modes.net_input_beast_port) {
s = makeBeastInputService();
serviceListen(s, Modes.net_bind_address, Modes.net_input_beast_port);
}
if (Modes.net_http_port) {
s = serviceInit("HTTP server", NULL, NULL, "\r\n\r\n", handleHTTPRequest);
serviceListen(s, Modes.net_bind_address, Modes.net_http_port);
}
s = serviceInit("HTTP server", NULL, NULL, "\r\n\r\n", handleHTTPRequest);
serviceListen(s, Modes.net_bind_address, Modes.net_http_ports);
}
//
//=========================================================================
@ -248,8 +263,9 @@ static struct client * modesAcceptClients(void) {
struct net_service *s;
for (s = Modes.services; s; s = s->next) {
if (s->listen_fd >= 0) {
while ((fd = anetTcpAccept(Modes.aneterr, s->listen_fd, NULL, &port)) >= 0) {
int i;
for (i = 0; i < s->listener_count; ++i) {
while ((fd = anetTcpAccept(Modes.aneterr, s->listener_fds[i], NULL, &port)) >= 0) {
createSocketClient(s, fd);
}
}

View file

@ -33,7 +33,8 @@ typedef void (*heartbeat_fn)(struct net_service *);
struct net_service {
struct net_service* next;
const char *descr;
int listen_fd;
int listener_count; // number of listeners
int *listener_fds; // listening FDs
int connections; // number of active clients
@ -63,7 +64,7 @@ struct net_writer {
struct net_service *serviceInit(const char *descr, struct net_writer *writer, heartbeat_fn hb_handler, const char *sep, read_fn read_handler);
struct client *serviceConnect(struct net_service *service, char *addr, int port);
void serviceListen(struct net_service *service, char *bind_addr, int bind_port);
void serviceListen(struct net_service *service, char *bind_addr, char *bind_ports);
struct client *createSocketClient(struct net_service *service, int fd);
struct client *createGenericClient(struct net_service *service, int fd);

View file

@ -155,7 +155,7 @@ void display_stats(struct stats *st) {
printf("%u unique aircraft tracks\n", st->unique_aircraft);
printf("%u aircraft tracks where only one message was seen\n", st->single_message_aircraft);
if (Modes.net && Modes.net_http_port)
if (Modes.net)
printf("%d HTTP requests\n", st->http_requests);
{

View file

@ -149,7 +149,7 @@ int main(int argc, char **argv) {
struct client *c;
struct net_service *s;
char *bo_connect_ipaddr = "127.0.0.1";
int bo_connect_port = MODES_NET_OUTPUT_BEAST_PORT;
int bo_connect_port = 30005;
// Set sane defaults