Skip to content

Commit

Permalink
iiod: Enable iiod to listen on non-standard ports
Browse files Browse the repository at this point in the history
This enables iiod to take a new command line argument "-p <num>" which
is port number. This effects both:
 - the port number that iiod listens on
 - the advertised port number that is used with Avahi

<num> can be any of:
             0 : uses a random/free dynamic port
    1 to  1023 : System Ports (must be root)
 1024 to 49151 : User Ports
49152 to 65535 : Dynamic Ports, or Ephemeral

This allows multiple instances of iiod to be used on the same machine,
as well as just using it on different network ports, making it easier to
bind behind ssh or something that provides security.

Signed-off-by: Robin Getz <[email protected]>
  • Loading branch information
rgetz authored and pcercuei committed Mar 24, 2022
1 parent f9e0171 commit 1363aab
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 26 deletions.
18 changes: 10 additions & 8 deletions iiod/dns-sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ static struct avahi_data {
AvahiClient *client;
AvahiEntryGroup *group;
char * name;
uint16_t port;
} avahi;

static void create_services(AvahiClient *c);
Expand Down Expand Up @@ -85,17 +86,17 @@ static void __avahi_group_cb(AvahiEntryGroup *group,

switch (state) {
case AVAHI_ENTRY_GROUP_ESTABLISHED :
IIO_INFO("Avahi: Service "%s" successfully established.\n",
avahi.name);
IIO_INFO("Avahi: Service "%s:%hu" successfully established.\n",
avahi.name, avahi.port);
break;
case AVAHI_ENTRY_GROUP_COLLISION : {
char *n;
/* A service name collision, pick a new name */
n = avahi_alternative_service_name(avahi.name);
avahi_free(avahi.name);
avahi.name = n;
IIO_INFO("Avahi: Group Service name collision, renaming service to "%s"\n",
avahi.name);
IIO_INFO("Avahi: Group Service name collision, renaming service to "%s:%hu"\n",
avahi.name, avahi.port);
create_services(avahi_entry_group_get_client(group));
break;
}
Expand Down Expand Up @@ -208,7 +209,7 @@ static void create_services(AvahiClient *c)

ret = avahi_entry_group_add_service(avahi.group,
AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
0, avahi.name, "_iio._tcp", NULL, NULL, IIOD_PORT, NULL);
0, avahi.name, "_iio._tcp", NULL, NULL, avahi.port, NULL);
if (ret < 0) {
if (ret == AVAHI_ERR_COLLISION) {
char *n;
Expand All @@ -231,8 +232,8 @@ static void create_services(AvahiClient *c)
goto fail;
}

IIO_INFO("Avahi: Registered "%s" to ZeroConf server %s\n",
avahi.name, avahi_client_get_version_string(c));
IIO_INFO("Avahi: Registered "%s:%hu" to ZeroConf server %s\n",
avahi.name, avahi.port, avahi_client_get_version_string(c));

return;

Expand Down Expand Up @@ -296,7 +297,7 @@ static void start_avahi_thd(struct thread_pool *pool, void *d)
}
}

void start_avahi(struct thread_pool *pool)
void start_avahi(struct thread_pool *pool, uint16_t port)
{
int ret;
char err_str[1024];
Expand All @@ -307,6 +308,7 @@ void start_avahi(struct thread_pool *pool)
avahi.client = NULL;
avahi.group = NULL;
avahi.name = NULL;
avahi.port = port;

/* In case dbus, or avahi deamon are not started, we create a thread
* that tries a few times to attach, if it can't within the first
Expand Down
4 changes: 3 additions & 1 deletion iiod/dns-sd.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
#ifndef __IIOD_DNS_SD_H
#define __IIOD_DNS_SD_H

#include <stdint.h>

struct thread_pool;

void start_avahi(struct thread_pool *pool);
void start_avahi(struct thread_pool *pool, uint16_t port);
void stop_avahi(void);

#endif /* __IIOD_DNS_SD_H */
57 changes: 40 additions & 17 deletions iiod/iiod.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@

#define MY_NAME "iiod"

#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)

struct client_data {
int fd;
bool debug;
Expand All @@ -49,24 +52,12 @@ struct thread_pool *main_thread_pool;

static struct sockaddr_in sockaddr = {
.sin_family = AF_INET,
#if __BYTE_ORDER == __LITTLE_ENDIAN
.sin_addr.s_addr = __bswap_constant_32(INADDR_ANY),
.sin_port = __bswap_constant_16(IIOD_PORT),
#else
.sin_addr.s_addr = INADDR_ANY,
.sin_port = IIOD_PORT,
#endif
};

#ifdef HAVE_IPV6
static struct sockaddr_in6 sockaddr6 = {
.sin6_family = AF_INET6,
.sin6_addr = IN6ADDR_ANY_INIT,
#if __BYTE_ORDER == __LITTLE_ENDIAN
.sin6_port = __bswap_constant_16(IIOD_PORT),
#else
.sin6_port = IIOD_PORT,
#endif
};
#endif /* HAVE_IPV6 */

Expand All @@ -80,6 +71,7 @@ static const struct option options[] = {
{"ffs", required_argument, 0, 'F'},
{"nb-pipes", required_argument, 0, 'n'},
{"serial", required_argument, 0, 's'},
{"port", required_argument, 0, 'p'},
{0, 0, 0, 0},
};

Expand All @@ -93,6 +85,7 @@ static const char *options_descriptions[] = {
"Use the given FunctionFS mountpoint to serve over USB",
"Specify the number of USB pipes (ep couples) to use",
"Run " MY_NAME " on the specified UART.",
"Port to listen on (default = " STRINGIFY(IIOD_PORT) ").",
};

static void usage(void)
Expand Down Expand Up @@ -166,7 +159,8 @@ static int main_interactive(struct iio_context *ctx, bool verbose, bool use_aio,
}

static int main_server(struct iio_context *ctx, bool debug,
const void *xml_zstd, size_t xml_zstd_len)
const void *xml_zstd, size_t xml_zstd_len,
uint16_t port)
{
int ret, fd = -1, yes = 1,
keepalive_time = 10,
Expand All @@ -180,7 +174,12 @@ static int main_server(struct iio_context *ctx, bool debug,
LIBIIO_VERSION_MAJOR, LIBIIO_VERSION_MINOR,
LIBIIO_VERSION_GIT);

sockaddr.sin_port = htons(port);
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

#ifdef HAVE_IPV6
sockaddr6.sin6_port = htons(port);

fd = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);
#endif
ipv6 = (fd >= 0);
Expand Down Expand Up @@ -211,6 +210,21 @@ static int main_server(struct iio_context *ctx, bool debug,
goto err_close_socket;
}

/* if port == 0, the OS will return something in the ephemeral port range
* which we need to find, to pass to avahi
*/
if (!port) {
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
if (getsockname(fd, (struct sockaddr *)&sin, &len) == -1) {
iio_strerror(errno, err_str, sizeof(err_str));
IIO_ERROR("getsockname failed : %s\n", err_str);
goto err_close_socket;
}
port = ntohs(sin.sin_port);
/* we don't use sockaddr or sockaddr6 anymore, so ignore those */
}

if (ipv6)
IIO_INFO("IPv6 support enabled\n");

Expand All @@ -221,7 +235,7 @@ static int main_server(struct iio_context *ctx, bool debug,
}

if (HAVE_AVAHI)
start_avahi(main_thread_pool);
start_avahi(main_thread_pool, port);

pfd[0].fd = fd;
pfd[0].events = POLLIN;
Expand Down Expand Up @@ -353,7 +367,7 @@ static void *get_xml_zstd_data(const struct iio_context *ctx, size_t *out_len)
int main(int argc, char **argv)
{
bool debug = false, interactive = false, use_aio = false;
long nb_pipes = 3;
long nb_pipes = 3, val;
char *end;
struct iio_context *ctx;
int c, option_index = 0;
Expand All @@ -362,9 +376,10 @@ int main(int argc, char **argv)
char err_str[1024];
void *xml_zstd;
size_t xml_zstd_len = 0;
uint16_t port = IIOD_PORT;
int ret;

while ((c = getopt_long(argc, argv, "+hVdDiaF:n:s:",
while ((c = getopt_long(argc, argv, "+hVdDiaF:n:s:p:",
options, &option_index)) != -1) {
switch (c) {
case 'd':
Expand Down Expand Up @@ -414,6 +429,14 @@ int main(int argc, char **argv)

uart_params = optarg;
break;
case 'p':
val = strtoul(optarg, &end, 10);
if (optarg == end || (end && *end != '\0') || val > 0xFFFF || val < 0) {
IIO_ERROR("IIOD invalid port number\n");
return EXIT_FAILURE;
}
port = (uint16_t)val;
break;
case 'h':
usage();
return EXIT_SUCCESS;
Expand Down Expand Up @@ -477,7 +500,7 @@ int main(int argc, char **argv)
if (interactive)
ret = main_interactive(ctx, debug, use_aio, xml_zstd, xml_zstd_len);
else
ret = main_server(ctx, debug, xml_zstd, xml_zstd_len);
ret = main_server(ctx, debug, xml_zstd, xml_zstd_len, port);

/*
* In case we got here through an error in the main thread make sure all
Expand Down

0 comments on commit 1363aab

Please sign in to comment.