Hello community,

here is the log from the commit of package ser2net for openSUSE:Factory checked 
in at 2020-11-06 23:44:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ser2net (Old)
 and      /work/SRC/openSUSE:Factory/.ser2net.new.11331 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ser2net"

Fri Nov  6 23:44:27 2020 rev:16 rq:845612 version:4.3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/ser2net/ser2net.changes  2020-10-21 
14:38:12.821599525 +0200
+++ /work/SRC/openSUSE:Factory/.ser2net.new.11331/ser2net.changes       
2020-11-06 23:44:54.927284873 +0100
@@ -1,0 +2,7 @@
+Thu Oct 29 19:37:25 UTC 2020 - Martin Hauke <mar...@gmx.de>
+
+- Update to version 4.3.0
+  * Add mDNS support in ser2net for advertising.
+  * Some minor bug fixes.
+
+-------------------------------------------------------------------

Old:
----
  ser2net-4.2.3.tar.gz

New:
----
  ser2net-4.3.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ser2net.spec ++++++
--- /var/tmp/diff_new_pack.DkQv0h/_old  2020-11-06 23:44:55.455283858 +0100
+++ /var/tmp/diff_new_pack.DkQv0h/_new  2020-11-06 23:44:55.459283851 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           ser2net
-Version:        4.2.3
+Version:        4.3.0
 Release:        0
 Summary:        Serial port to network proxy
 License:        GPL-2.0-or-later
@@ -30,7 +30,7 @@
 BuildRequires:  libtool
 BuildRequires:  pkgconfig
 BuildRequires:  systemd-rpm-macros
-BuildRequires:  pkgconfig(libgensio)
+BuildRequires:  pkgconfig(libgensio) >= 2.2.0
 BuildRequires:  pkgconfig(yaml-0.1)
 %{?systemd_requires}
 

++++++ ser2net-4.2.3.tar.gz -> ser2net-4.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ser2net-4.2.3/Makefile.am 
new/ser2net-4.3.0/Makefile.am
--- old/ser2net-4.2.3/Makefile.am       2020-10-06 14:24:49.000000000 +0200
+++ new/ser2net-4.3.0/Makefile.am       2020-10-29 03:53:26.000000000 +0100
@@ -4,7 +4,8 @@
 AM_CPPFLAGS = -DSYSCONFDIR="\"${sysconfdir}\"" -DDATAROOT="\"${datarootdir}\""
 ser2net_SOURCES = controller.c dataxfer.c readconfig.c port.c \
        ser2net.c led.c led_sysfs.c yamlconf.c auth.c gbuf.c trace.c \
-       portconfig.c ser2net_str.c portinfo.c rotator.c defaults.c
+       portconfig.c ser2net_str.c portinfo.c rotator.c defaults.c \
+       addsysattrs.c
 noinst_HEADERS = controller.h dataxfer.h readconfig.h defaults.h \
        ser2net.h led.h led_sysfs.h absout.h gbuf.h port.h
 man_MANS = ser2net.8 ser2net.yaml.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ser2net-4.2.3/addsysattrs.c 
new/ser2net-4.3.0/addsysattrs.c
--- old/ser2net-4.2.3/addsysattrs.c     1970-01-01 01:00:00.000000000 +0100
+++ new/ser2net-4.3.0/addsysattrs.c     2020-10-29 03:53:26.000000000 +0100
@@ -0,0 +1,287 @@
+/*
+ *  ser2net - A program for allowing telnet connection to serial ports
+ *  Copyright (C) 2015-2020  Corey Minyard <miny...@acm.org>
+ *  Copyright (C) 2015 I2SE GmbH <i...@i2se.com>
+ *  Copyright (C) 2016 Michael Heimpold <m...@heimpold.de>
+ *
+ *  SPDX-License-Identifier: GPL-2.0-only
+ *
+ *  In addition, as a special exception, the copyright holders of
+ *  ser2net give you permission to combine ser2net with free software
+ *  programs or libraries that are released under the GNU LGPL and
+ *  with code included in the standard release of OpenSSL under the
+ *  OpenSSL license (or modified versions of such code, with unchanged
+ *  license). You may copy and distribute such a system following the
+ *  terms of the GNU GPL for ser2net and the licenses of the other code
+ *  concerned, provided that you include the source code of that
+ *  other code when and as the GNU GPL requires distribution of source
+ *  code.
+ *
+ *  Note that people who make modified versions of ser2net are not
+ *  obligated to grant this special exception for their modified
+ *  versions; it is their choice whether to do so. The GNU General
+ *  Public License gives permission to release a modified version
+ *  without this exception; this exception also makes it possible to
+ *  release a modified version which carries forward this exception.
+ */
+
+#ifdef linux
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <gensio/gensio.h>
+#include <gensio/argvutils.h>
+#include "ser2net.h"
+#include "port.h"
+
+#define SYSFS_TTY_BASE "/sys/class/tty/"
+#define SYSFS_TTY_BASE_LEN 15
+
+static const char *
+get_base_str(const char *devname, unsigned int *len)
+{
+    const char *e, *s;
+
+    s = strstr(devname, ",serialdev");
+    if (s) {
+       s = strchr(s, ',');
+       if (s)
+           s++;
+    } else {
+       s = strstr(devname, "/dev/");
+    }
+    if (s) {
+       e = strchr(s, ',');
+       if (e)
+           *len = e - s;
+       else
+           *len = strlen(s);
+    }
+
+    return s;
+}
+
+static void
+add_attr(struct absout *eout, const char *portname,
+        const char *path, const char *sysfsname,
+        const char ***txt, gensiods *args, gensiods *argc)
+{
+    char *s, buf[1024];
+    ssize_t rv;
+    int fd;
+
+    s = gensio_alloc_sprintf(so, "%s/%s", path, sysfsname);
+    if (!s) {
+       eout->out(eout,
+                 "Device %s: Unable to allocate path for %s: out of memory\n",
+                 portname, sysfsname);
+       return;
+    }
+
+    fd = open(s, O_RDONLY);
+    so->free(so, s);
+    if (fd < 0)
+       /* Some of these are options, just ignore open errors. */
+       return;
+ retry:
+    rv = read(fd, buf, sizeof(buf) - 1);
+    if (rv < 0) {
+       if (errno == EINTR)
+           goto retry;
+       eout->out(eout,
+                 "Device %s: Unable to read contents of %s: %s\n",
+                 portname, sysfsname, strerror(errno));
+       goto out;
+    }
+    while (rv > 0 && isspace(buf[rv - 1]))
+       rv--;
+    buf[rv] = '\0';
+
+    rv = gensio_argv_sappend(so, txt, args, argc, "%s=%s", sysfsname, buf);
+    if (rv < 0)
+       eout->out(eout,
+                 "Device %s: Unable add txt contents for %s: %s\n",
+                 portname, sysfsname, gensio_err_to_str(rv));
+ out:
+    close(fd);
+}
+
+void
+add_usb_attrs(struct absout *eout, const char *portname, const char *devstr,
+             char *path, const char ***txt, gensiods *args, gensiods *argc)
+{
+    int rv;
+    char *p, *s;
+    unsigned int len;
+
+    rv = gensio_argv_sappend(so, txt, args, argc, "devicetype=serialusb");
+    if (rv < 0)
+       eout->out(eout,
+                 "Device %s: Unable add txt devicetype for %s\n",
+                 portname, gensio_err_to_str(rv));
+
+    /* Search backwards three directory levels, the name should match. */
+    s = p = strrchr(path, '/');
+    if (p && p > path) {
+       p--;
+       while (p > path && *p != '/')
+           p--;
+    }
+    if (p && p > path) {
+       s = p;
+       p--;
+       while (p > path && *p != '/')
+           p--;
+    }
+    len = strlen(devstr);
+    if (!p || (s - p - 1 != len) || strncmp(p + 1, devstr, len)) {
+       eout->out(eout,
+                 "Device %s: usb path is not valid: %s\n",
+                 portname, path);
+       return;
+    }
+    *p = '\0';
+
+    add_attr(eout, portname, path, "bInterfaceNumber", txt, args, argc);
+    add_attr(eout, portname, path, "interface", txt, args, argc);
+
+    p = strrchr(path, '/');
+    if (!p || p == path) {
+       eout->out(eout,
+                 "Device %s: usb path(2) is not valid: %s\n",
+                 portname, path);
+       return;
+    }
+    *p = '\0';
+    
+    add_attr(eout, portname, path, "idProduct", txt, args, argc);
+    add_attr(eout, portname, path, "idVendor", txt, args, argc);
+    add_attr(eout, portname, path, "serial", txt, args, argc);
+    add_attr(eout, portname, path, "manufacturer", txt, args, argc);
+    add_attr(eout, portname, path, "product", txt, args, argc);
+}
+
+static int
+follow_symlink(char *path)
+{
+    char path2[PATH_MAX], *s, *t;
+    int rv;
+
+    do {
+       rv = readlink(path, path2, sizeof(path2) - 1);
+       if (rv < 0) {
+           if (errno == EINVAL)
+               break;
+           goto out_err;
+       }
+       path2[rv] = '\0';
+
+       s = path2;
+       if (*s == '/') {
+           t = path;
+       } else {
+           t = path + strlen(path);
+           while (t > path && *(t - 1) != '/')
+               t--;
+           while (strcmp(s, "../") == 0) {
+               if (t > path)
+                   t--;
+               while (t > path && *(t - 1) != '/')
+                   t--;
+               s += 3;
+           }
+           if (t == path)
+               goto out_err;
+           if (strlen(s) + (t - path) > PATH_MAX)
+               goto out_err;
+       }
+       strcpy(t, s);
+    } while(true);
+
+    return 0;
+
+ out_err:
+    return -EINVAL;
+}
+
+void
+add_sys_attrs(struct absout *eout, const char *portname,
+             const char *devname,
+             const char ***txt, gensiods *args, gensiods *argc)
+{
+    const char *d, *s, *t;
+    unsigned int len;
+    char path[PATH_MAX], path2[PATH_MAX], devstr[128];
+    ssize_t rv;
+
+    /* Find the /dev/xxx string in the device name. */
+    d = get_base_str(devname, &len);
+    if (!d)
+       return;
+    if (len == 0 || len > sizeof(path) - 1) {
+       eout->out(eout, "Device %s: device name too long.\n", portname);
+       return;
+    }
+    memcpy(path, d, len);
+    path[len] = 0;
+
+    if (follow_symlink(path)) {
+       eout->out(eout, "Device %s: Could not follow symlink: %s\n", path,
+                 portname);
+       return;
+    }
+
+    /* Find the name used in sysfs, usually what is after /dev. */
+    t = s = path + strlen(path);
+    while (s != path && *s != '/')
+       s--;
+    len = t - s;
+    if (len == 0 || len > sizeof(devstr) - 1) {
+       eout->out(eout, "Device %s: base device name size invalid.\n", 
portname);
+       return;
+    }
+    memcpy(devstr, s + 1, len);
+    devstr[len] = '\0';
+
+    /* Find the tty class link at /sys/class/tty/<devname> */
+    snprintf(path2, sizeof(path2), "%s%s", SYSFS_TTY_BASE, devstr);
+
+    /* The tty class is a link, find the real location. */
+    memcpy(path, SYSFS_TTY_BASE, SYSFS_TTY_BASE_LEN);
+    rv = readlink(path2, path + SYSFS_TTY_BASE_LEN,
+                 sizeof(path) - SYSFS_TTY_BASE_LEN - 1);
+    if (rv < 0) {
+       eout->out(eout,
+                 "Device %s: Unable to get symlink path at %s: %s\n",
+                 portname, path2, strerror(errno));
+       return;
+    }
+    path[rv + SYSFS_TTY_BASE_LEN] = '\0';
+
+    if (strstr(path, "/usb")) {
+       add_usb_attrs(eout, portname, devstr, path, txt, args, argc);
+    } else {
+       rv = gensio_argv_sappend(so, txt, args, argc, "devicetype=serial");
+       if (rv < 0)
+           eout->out(eout,
+                     "Device %s: Unable add txt devicetype for %s\n",
+                     portname, gensio_err_to_str(rv));
+    }
+}
+
+#else
+
+void
+add_sys_attrs(struct absout *eout, const char *portname,
+             const char *devname,
+             const char ***txt, gensiods *args, gensiods *argc)
+{
+}
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ser2net-4.2.3/configure.ac 
new/ser2net-4.3.0/configure.ac
--- old/ser2net-4.2.3/configure.ac      2020-10-06 14:24:49.000000000 +0200
+++ new/ser2net-4.3.0/configure.ac      2020-10-29 03:53:26.000000000 +0100
@@ -1,4 +1,4 @@
-AC_INIT([ser2net], [4.2.3], [miny...@acm.org])
+AC_INIT([ser2net], [4.3.0], [miny...@acm.org])
 AM_INIT_AUTOMAKE([-Wall])
 AC_PROG_CC
 AM_PROG_AR
@@ -57,6 +57,6 @@
 AC_CHECK_HEADER(yaml.h, [],
    [AC_MSG_ERROR([yaml.h not found, please install libyaml dev package])])
 AC_CHECK_LIB(yaml, yaml_document_initialize, [],
-   [AC_MSG_ERROR([libyaml won't link, please install gensio dev package])])
+   [AC_MSG_ERROR([libyaml won't link, please install libyaml dev package])])
 
 AC_OUTPUT([Makefile tests/Makefile])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ser2net-4.2.3/defaults.c new/ser2net-4.3.0/defaults.c
--- old/ser2net-4.2.3/defaults.c        2020-10-06 14:24:49.000000000 +0200
+++ new/ser2net-4.3.0/defaults.c        2020-10-29 03:53:26.000000000 +0100
@@ -78,6 +78,13 @@
     { "closeon",       GENSIO_DEFAULT_STR,     .def.strval = NULL },
     { "banner",                GENSIO_DEFAULT_STR,     .def.strval = NULL },
     { "sendon",                GENSIO_DEFAULT_STR,     .def.strval = NULL },
+    { "mdns",          GENSIO_DEFAULT_BOOL,    .def.intval = 0 },
+    { "mdns-sysattrs", GENSIO_DEFAULT_BOOL,    .def.intval = 0 },
+    { "mdns-type",     GENSIO_DEFAULT_STR,     .def.strval = NULL },
+    { "mdns-domain",   GENSIO_DEFAULT_STR,     .def.strval = NULL },
+    { "mdns-host",     GENSIO_DEFAULT_STR,     .def.strval = NULL },
+    { "mdns-interface",        GENSIO_DEFAULT_INT,     .min=-1, .max=100000,
+                                       .def.intval = -1},
     { NULL }
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ser2net-4.2.3/port.c new/ser2net-4.3.0/port.c
--- old/ser2net-4.2.3/port.c    2020-10-06 14:24:49.000000000 +0200
+++ new/ser2net-4.3.0/port.c    2020-10-29 03:53:26.000000000 +0100
@@ -25,12 +25,17 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <stdio.h>
 #include <errno.h>
 #include <syslog.h>
 #include <assert.h>
 #include "ser2net.h"
 #include "port.h"
 #include "gbuf.h"
+#include <gensio/gensio_mdns.h>
+#include <gensio/argvutils.h>
+#include <gensio/gensio_err.h>
+#include <gensio/sergensio.h>
 
 struct gensio_lock *ports_lock;
 port_info_t *ports = NULL; /* Linked list of ports. */
@@ -271,6 +276,214 @@
     }
 }
 
+#ifdef DO_MDNS
+static struct gensio_mdns *mdns;
+
+static char *
+derive_mdns_type(port_info_t *port)
+{
+    /* Get a mdns type based on the gensio. */
+    unsigned int i;
+    const char *type, *ntype = "_iostream._tcp";
+
+    type = gensio_acc_get_type(port->accepter, 0);
+    for (i = 1; type; i++) {
+       if (strcmp(type, "tcp") == 0)
+           break;
+       if (strcmp(type, "udp") == 0) {
+           ntype = "_iostream._udp";
+           break;
+       }
+       type = gensio_acc_get_type(port->accepter, i);
+    }
+    return strdup(ntype);
+}
+
+static void
+mdns_addprovider(struct absout *eout, port_info_t *port)
+{
+    gensiods i;
+    static char *provstr = "provider=";
+    char *tmps = NULL;
+
+    for (i = 0; i < port->mdns_txt_argc; i++) {
+       if (strncmp(port->mdns_txt[i], provstr, strlen(provstr)) == 0)
+           /* User already specified it, don't override. */
+           return;
+    }
+
+    tmps = gensio_alloc_sprintf(so, "%s%s", provstr, "ser2net");
+    if (!tmps)
+       goto out_nomem;
+
+    if (gensio_argv_append(so, &port->mdns_txt, tmps,
+                          &port->mdns_txt_args, &port->mdns_txt_argc,
+                          false))
+       goto out_nomem;
+    return;
+
+ out_nomem:
+    eout->out(eout, "Error allocation mdns provider for %s: out of memory",
+             port->name);
+    if (tmps)
+       so->free(so, tmps);
+}
+
+static void
+mdns_addstack(struct absout *eout, port_info_t *port)
+{
+    gensiods i;
+    static char *stackstr = "gensiostack=";
+    const char *type;
+    char *stack = NULL, *tmps = NULL;
+
+    for (i = 0; i < port->mdns_txt_argc; i++) {
+       if (strncmp(port->mdns_txt[i], stackstr, strlen(stackstr)) == 0)
+           /* User already specified it, don't override. */
+           return;
+    }
+
+    for (i = 0; ; i++) {
+       type = gensio_acc_get_type(port->accepter, i);
+       if (!type)
+           break;
+
+       if (strcmp(type, "telnet") == 0) {
+           struct gensio_accepter *telnet_acc =
+               gensio_acc_get_child(port->accepter, i);
+           const char *rfc2217 = "";
+
+           if (gensio_acc_to_sergensio_acc(telnet_acc))
+               rfc2217 = "(rfc2217)";
+
+           tmps = gensio_alloc_sprintf(so, "%s%s%s%s",
+                                       stack ? stack : "", stack ? "," : "",
+                                       type, rfc2217);
+       } else {
+           tmps = gensio_alloc_sprintf(so, "%s%s%s",
+                                       stack ? stack : "", stack ? "," : "",
+                                       type);
+       }
+       if (!tmps)
+           goto out_nomem;
+       if (stack)
+           so->free(so, stack);
+       stack = tmps;
+    }
+
+    if (!stack)
+       return;
+
+    tmps = gensio_alloc_sprintf(so, "%s%s", stackstr, stack);
+    if (!tmps)
+       goto out_nomem;
+    stack = tmps;
+
+    if (gensio_argv_append(so, &port->mdns_txt, stack,
+                          &port->mdns_txt_args, &port->mdns_txt_argc,
+                          false))
+       goto out_nomem;
+    return;
+
+ out_nomem:
+    eout->out(eout, "Error allocation mdns stack for %s: out of memory",
+             port->name);
+    if (stack)
+       so->free(so, stack);
+}
+
+static void
+mdns_setup(struct absout *eout, port_info_t *port)
+{
+    int err;
+    char portnum_str[20];
+    gensiods portnum_len = sizeof(portnum_str);
+
+    if (!mdns || !port->mdns)
+       return;
+
+    if (!port->mdns_port) {
+       strcpy(portnum_str, "0");
+       err = gensio_acc_control(port->accepter, GENSIO_CONTROL_DEPTH_FIRST,
+                                true, GENSIO_ACC_CONTROL_LPORT, portnum_str,
+                                &portnum_len);
+       if (err) {
+           eout->out(eout, "Can't get mdns port for device %s: %s",
+                     port->name, gensio_err_to_str(err));
+           return;
+       }
+       port->mdns_port = strtoul(portnum_str, NULL, 0);
+    }
+
+    if (!port->mdns_type) {
+       port->mdns_type = derive_mdns_type(port);
+       if (!port->mdns_type) {
+           eout->out(eout, "Can't alloc mdns type for %s: out of memory",
+                     port->name);
+           return;
+       }
+    }
+
+    if (!port->mdns_name) {
+       port->mdns_name = strdup(port->name);
+       if (!port->mdns_name) {
+           eout->out(eout, "Can't alloc mdns name for %s: out of memory",
+                     port->name);
+           return;
+       }
+    }
+
+    mdns_addprovider(eout, port);
+    mdns_addstack(eout, port);
+
+    /*
+     * Always stick on the NULL, that doesn't update argc so it's safe,
+     * a new txt will just write over the NULL we added.
+     */
+    err = gensio_argv_append(so, &port->mdns_txt, NULL,
+                            &port->mdns_txt_args, &port->mdns_txt_argc, true);
+    if (err) {
+       eout->out(eout, "Error terminating mdns-txt for %s: %s",
+                 port->name, gensio_err_to_str(err));
+       return;
+    }
+
+    if (port->do_mdns_sysattrs)
+       add_sys_attrs(eout, port->name, port->devname, &port->mdns_txt,
+                     &port->mdns_txt_args, &port->mdns_txt_argc);
+
+    err = gensio_mdns_add_service(mdns, port->mdns_interface,
+                                 port->mdns_nettype,
+                                 port->mdns_name, port->mdns_type,
+                                 port->mdns_domain, port->mdns_host,
+                                 port->mdns_port, port->mdns_txt,
+                                 &port->mdns_service);
+    if (err)
+       eout->out(eout, "Can't add mdns service for device %s: %s",
+                 port->name, gensio_err_to_str(err));
+}
+
+static void
+mdns_shutdown(port_info_t *port)
+{
+    if (port->mdns_service)
+       gensio_mdns_remove_service(port->mdns_service);
+    port->mdns_service = NULL;
+}
+
+#else
+
+static void
+mdns_setup(struct absout *eout, port_info_t *port)
+{
+}
+
+static void
+mdns_shutdown(port_info_t *port)
+{
+}
+#endif /* DO_MDNS */
+
 int
 startup_port(struct absout *eout, port_info_t *port)
 {
@@ -290,6 +503,8 @@
     port->dev_to_net_state = PORT_UNCONNECTED;
     port->net_to_dev_state = PORT_UNCONNECTED;
 
+    mdns_setup(eout, port);
+
     if (port->connbacks) {
        err = port_dev_enable(port);
        if (err) {
@@ -390,6 +605,7 @@
            check_port_new_net(port, netcon);
     } else {
        /* Port was disabled, shut it down. */
+       mdns_shutdown(port);
        gensio_acc_shutdown(port->accepter, NULL, NULL);
        call_port_op_done(port);
     }
@@ -1028,6 +1244,13 @@
        goto out;
     }
 
+#ifdef DO_MDNS
+    rv = gensio_alloc_mdns(so, &mdns);
+    if (rv)
+       /* Not fatal */
+       fprintf(stderr, "Unable to start mdns: %s\n", gensio_err_to_str(rv));
+#endif /* DO_MDNS */
+
     rv = init_rotators();
 
  out:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ser2net-4.2.3/port.h new/ser2net-4.3.0/port.h
--- old/ser2net-4.2.3/port.h    2020-10-06 14:24:49.000000000 +0200
+++ new/ser2net-4.3.0/port.h    2020-10-29 03:53:26.000000000 +0100
@@ -30,6 +30,12 @@
 #include <sys/time.h>
 #include "gbuf.h"
 #include "absout.h"
+#include <gensio/gensio.h>
+
+#if (defined(gensio_version_major) && (gensio_version_major > 2 ||     \
+     (gensio_version_major == 2 && gensio_version_minor >= 2)))
+#define DO_MDNS
+#endif
 
 /* States for the net_to_dev_state and dev_to_net_state. */
 #define PORT_CLOSED                    0 /* The accepter is disabled. */
@@ -332,6 +338,25 @@
     char *sendon;
     gensiods sendon_pos;
     gensiods sendon_len;
+
+#ifdef DO_MDNS
+    /*
+     * mdns info
+     */
+    bool mdns;
+    bool do_mdns_sysattrs;
+    unsigned int mdns_port;
+    int mdns_interface;
+    int mdns_nettype;
+    char *mdns_name;
+    char *mdns_type;
+    char *mdns_domain;
+    char *mdns_host;
+    const char **mdns_txt;
+    gensiods mdns_txt_argc;
+    gensiods mdns_txt_args;
+    struct gensio_mdns_service *mdns_service;
+#endif /* DO_MDNS */
 };
 
 /* In dataxfer.c */
@@ -393,4 +418,9 @@
 void setup_trace(port_info_t *port);
 void shutdown_trace(port_info_t *port);
 
+/* In addsyattrs.c */
+void add_sys_attrs(struct absout *eout, const char *portname,
+                  const char *devname,
+                  const char ***txt, gensiods *args, gensiods *argc);
+
 #endif /* PORT */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ser2net-4.2.3/portconfig.c 
new/ser2net-4.3.0/portconfig.c
--- old/ser2net-4.2.3/portconfig.c      2020-10-06 14:24:49.000000000 +0200
+++ new/ser2net-4.3.0/portconfig.c      2020-10-29 03:53:26.000000000 +0100
@@ -29,6 +29,7 @@
 #include <ctype.h>
 #include <assert.h>
 #include <gensio/gensio.h>
+#include <gensio/argvutils.h>
 #include "ser2net.h"
 #include "port.h"
 #include "absout.h"
@@ -330,6 +331,18 @@
        free(port->orig_devname);
     if (port->sendon)
        free(port->sendon);
+#ifdef DO_MDNS
+    if (port->mdns_name)
+       free(port->mdns_name);
+    if (port->mdns_type)
+       free(port->mdns_type);
+    if (port->mdns_domain)
+       free(port->mdns_domain);
+    if (port->mdns_host)
+       free(port->mdns_host);
+    if (port->mdns_txt)
+       gensio_argv_free(so, port->mdns_txt);
+#endif /* DO_MDNS */
     free(port);
 }
 
@@ -362,16 +375,19 @@
     port->free_count = 1;
 
     /* Make sure all the timers are stopped. */
-    err = so->stop_timer_with_done(port->send_timer,
-                                  gen_timer_shutdown_done, port);
-    if (err != GE_TIMEDOUT)
-       port->free_count++;
-
-    err = so->stop_timer_with_done(port->timer,
-                                  gen_timer_shutdown_done, port);
-    if (err != GE_TIMEDOUT)
-       port->free_count++;
+    if (port->send_timer) {
+       err = so->stop_timer_with_done(port->send_timer,
+                                      gen_timer_shutdown_done, port);
+       if (err != GE_TIMEDOUT)
+           port->free_count++;
+    }
 
+    if (port->timer) {
+       err = so->stop_timer_with_done(port->timer,
+                                      gen_timer_shutdown_done, port);
+       if (err != GE_TIMEDOUT)
+           port->free_count++;
+    }
     finish_free_port(port); /* Releases lock */
 }
 
@@ -453,6 +469,15 @@
     return 0;
 }
 
+#ifdef DO_MDNS
+static struct gensio_enum_val mdns_nettypes[] = {
+    { "unspec", GENSIO_NETTYPE_UNSPEC },
+    { "ipv4", GENSIO_NETTYPE_IPV4 },
+    { "ipv6", GENSIO_NETTYPE_IPV6 },
+    { NULL }
+};
+#endif /* DO_MDNS */
+
 static int
 myconfig(port_info_t *port, struct absout *eout, const char *pos)
 {
@@ -635,6 +660,65 @@
            free(port->sendon);
        port->sendon = fval;
        port->sendon_len = len;
+#ifdef DO_MDNS
+    } else if (gensio_check_keybool(pos, "mdns",
+                                   &port->mdns) > 0) {
+    } else if (gensio_check_keybool(pos, "mdns-sysattrs",
+                                   &port->do_mdns_sysattrs) > 0) {
+    } else if (gensio_check_keyuint(pos, "mdns-port",
+                                   &port->mdns_port) > 0) {
+    } else if (gensio_check_keyint(pos, "mdns-interface",
+                                  &port->mdns_interface) > 0) {
+    } else if (gensio_check_keyenum(pos, "mdns-nettype",
+                                   mdns_nettypes,
+                                   &port->mdns_nettype) > 0) {
+    } else if (gensio_check_keyvalue(pos, "mdns-name", &val) > 0) {
+       fval = strdup(val);
+       if (!fval) {
+           eout->out(eout, "Out of memory allocating mdns-name");
+           return -1;
+       }
+       if (port->mdns_name)
+           free(port->mdns_name);
+       port->mdns_name = fval;
+    } else if (gensio_check_keyvalue(pos, "mdns-type", &val) > 0) {
+       fval = strdup(val);
+       if (!fval) {
+           eout->out(eout, "Out of memory allocating mdns-type");
+           return -1;
+       }
+       if (port->mdns_type)
+           free(port->mdns_type);
+       port->mdns_type = fval;
+    } else if (gensio_check_keyvalue(pos, "mdns-domain", &val) > 0) {
+       fval = strdup(val);
+       if (!fval) {
+           eout->out(eout, "Out of memory allocating mdns-domain");
+           return -1;
+       }
+       if (port->mdns_domain)
+           free(port->mdns_domain);
+       port->mdns_domain = fval;
+    } else if (gensio_check_keyvalue(pos, "mdns-host", &val) > 0) {
+       fval = strdup(val);
+       if (!fval) {
+           eout->out(eout, "Out of memory allocating mdns-host");
+           return -1;
+       }
+       if (port->mdns_host)
+           free(port->mdns_host);
+       port->mdns_host = fval;
+    } else if (gensio_check_keyvalue(pos, "mdns-txt", &val) > 0) {
+       int err = gensio_argv_append(so, &port->mdns_txt, val,
+                                    &port->mdns_txt_args, &port->mdns_txt_argc,
+                                    true);
+
+       if (err) {
+           eout->out(eout, "Out of memory allocating mdns-txt: %s",
+                     gensio_err_to_str(err));
+           return -1;
+       }
+#endif /* DO_MDNS */
 
     /* Everything from here down to the banner, etc is deprecated. */
     } else if (strcmp(pos, "remctl") == 0) {
@@ -765,6 +849,18 @@
     port->led_tx = NULL;
     port->led_rx = NULL;
 
+#ifdef DO_MDNS
+    port->mdns = find_default_bool("mdns");
+    port->do_mdns_sysattrs = find_default_bool("mdns-sysattrs");
+    port->mdns_interface = find_default_int("mdns-interface");
+    if (find_default_str("mdns-type", &port->mdns_type))
+       return ENOMEM;
+    if (find_default_str("mdns-domain", &port->mdns_domain))
+       return ENOMEM;
+    if (find_default_str("mdns-host", &port->mdns_host))
+       return ENOMEM;
+#endif /* DO_MDNS */
+
     return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ser2net-4.2.3/ser2net.yaml 
new/ser2net-4.3.0/ser2net.yaml
--- old/ser2net-4.2.3/ser2net.yaml      2020-10-06 14:24:49.000000000 +0200
+++ new/ser2net-4.3.0/ser2net.yaml      2020-10-29 03:53:26.000000000 +0100
@@ -202,6 +202,46 @@
 #     banner: '''a Special Banner \d'''
 #     closeon: 'ctrl-a\001nil\000'
 
+# # An example showing mDNS support.  You must add "mdns: true" to enable
+# # mDNS on a port to enable it.  By default it uses the name for the mDNS
+# # name and "_iostream._xxx" for the type, where xxx is either tcp, udp
+# # or sctp base on the gensio type.  Everything else defaults.  Don't
+# # set mdns-host or mdns-domain unless you know what you are doing.
+# # mdns-txt can be specified multiple times to add multiple strings.
+# #
+# # mdns-sysattrs on Linux adds USB attributes to the txt data from
+# # sysfs.  If the serial port is a USB one, it will add the following
+# # txt fields:
+# #   devicetype=serialusb
+# #   bInterfaceNumber=...
+# #   interface=...
+# #   idProduct=...
+# #   idVendor=...
+# #   serial=...
+# #   manufacturer=...
+# #   product=...
+# # These fields are pulled straight from sysfs, see information on that
+# # for details on what these mean.  Not all the fields may be present
+# # depending on the specific USB device.  If you set this on a non-USB
+# # serial port, it will just add:
+# #   devicetype=serial
+# # This may be extended in the future for other OSes or other device
+# # interfaces.
+# connection: &rack-3-slot-5
+#   accepter: tcp,2034
+#   connector: echo
+#   options:
+#     mdns: true
+#     mdns-interface: -1
+#     mdns-nettype: unspec
+#     mdns-name: rack-3-slot-5
+#     mdns-type: "_iostream._tcp"
+#     mdns-domain: "local"
+#     mdns-host: "myhost.local"
+#     mdns-txt: "server=ser2net"
+#     mdns-txt: "type=echo"
+#     mdns-sysattrs: true
+
 # # An example showing all options and their defaults.  Note that empty
 # # strings are ok for most strings, but not for things that take filesname
 # # or are required to be aliases.
@@ -243,3 +283,11 @@
 #     closeon:
 #     connector-retry-time: 10
 #     accepter-retry-time: 10
+#     mdns: false
+#     mdns-interface: -1
+#     mdns-nettype: unspec
+#     mdns-name: con7
+#     mdns-type: "_iostream._tcp"
+#     mdns-domain: <NULL>
+#     mdns-host: <NULL>
+#     mdns-txt: <NULL>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ser2net-4.2.3/ser2net.yaml.5 
new/ser2net-4.3.0/ser2net.yaml.5
--- old/ser2net-4.2.3/ser2net.yaml.5    2020-10-06 14:24:49.000000000 +0200
+++ new/ser2net-4.3.0/ser2net.yaml.5    2020-10-29 03:53:26.000000000 +0100
@@ -440,6 +440,55 @@
 empty set of users, then no users are allowed.  This may be specified
 more than once, each one adds more users.
 
+.I mdns: true|false
+Enables/disables mdns support for the connection.  If you set this and
+mdns is available, ser2net will create a service on mdns for the port.
+
+.I mdns-interface: <num>
+Sets the specific network interface to advertise the device.  Defaults
+to -1, which means all network interfaces.
+
+.I mdns-nettype: unspec|ipv4|ipv6
+Sets which network type to provide for the device advertisement.
+Defaults to unspec, which means do ipv4 and ipv6.
+
+.I mdns-name: <string>
+Sets the name in the mDNS advertisement.  Defaults to the connection name.
+
+.I mdns-type: <string>
+Sets the type in the mDNS advertisement.  Defaults to "_iostream._xxx"
+where xxx is either tcp, udp # # or sctp base on the gensio type.
+
+.I mdns-domain: <string>
+Sets the name in the mDNS advertisement.  Defaults to the system
+setting.  Don't set this unless you really know what you are doing.
+
+.I mdns-host: <string>
+Sets the host in the mDNS advertisement.  Defaults to the system
+setting.  Don't set this unless you really know what you are doing.
+
+.I mdns-txt: <string>
+Adds a text string to the mDNS advertisement.  The string should be in
+the form "name=value".  You can put anything you want in the strings.
+Two default strings are added by ser2net: "provider=ser2net" and
+"gensiostack=..." where the stack of gensios is added, like
+"telnet(rfc2217),tcp)".  The idea of gensiostack is you can just tack
+on the address to the end an make a connection using str_to_gensio().
+
+.I mdns-sysattrs: true|false
+On Linux adds system attributes from sysfs for USB serial ports to the
+mDNS txt fields.  If the serial port is USB, it adds
+"devicetype=serialusb" and the following attributes from sysfs:
+bInterfaceNumber, interface, idProduct, idVendor, serial,
+manufacturer, product.  If they are not present in sysfs, they are not
+added.  If the serial port is not USB, then "devicetype=serial" is
+added.
+
+Note: Be *very* careful when using a gensiostack with str_to_gensio().
+Just blindly calling str_to_gensio() with it could result in
+significant security issues, as it can pass pty, stdio, trace,
+etc. gensios in it.  You must either validate that the stack is a safe
+set or just use it for information.  You have been warned.  Be careful.
 .SH "ROTATOR"
 A rotator allows a single network connection to connect to one of a
 number of connections.
@@ -543,18 +592,15 @@
 
 The following default values are specific to ser2net, given with their
 default values:
-
 .TP
 .B telnet_brk_on_sync: false
 If a telnet is received, send a break on the connected gensio (if
 applicable).  By default data is flushed until the data mark, but no
 break is sent.
-
 .TP
 .B kickolduser: false
 If a new user comes in on a connection that already has a user, kick
 off the previous user.
-
 .TP
 .B chardelay: true
 Enable asmall wait after each character received on the serial
@@ -563,7 +609,6 @@
 1000us, before sending on the TCP port.  This allows more efficient
 use of network resources when receiving large amounts of data, but
 gives reasonable interactivity.
-
 .TP
 .B chardelay-scale: 20
 sets the number of serial port characters, in tenths of a character,
@@ -577,17 +622,14 @@
 the calculation for chardelay-scale results in a value smaller than
 this number, this number will be used instead.  The default value
 is 1000.  This can range from 1-100000.
-
 .TP
 .B net-to-dev-bufsize: 64
 sets the size of the buffer reading from the network port and writing to the
 serial device.
-
 .TP
 .B dev-to-net-bufsize: 64
 sets the size of the buffer reading from the serial device and writing
 to the network port.
-
 .TP
 .B max-connections: 1
 set the maximum number of connections that can be made on this
@@ -595,7 +637,6 @@
 port, each ports output goes to the device, and the device output goes
 to all ports simultaneously.  See "MULTIPLE CONNECTIONS" below.
 for details.
-
 .TP
 .B remaddr: [!]<addr>[;[!]<addr>[;...]]
 specifies the allowed remote connections, where the addr is a standard
@@ -608,17 +649,26 @@
 connections (see max-connections) is reserved for that address.  If
 data comes in on the device, ser2net will attempt to connect to the
 address.  This works on TCP and UDP.
-
 .TP
 .B authdir: /usr/share/ser2net/auth
 The authentication directory for ser2net.  The AUTHENTICATION for more
 details.
-
 .TP
 .B authdir-admin: /etc/ser2net/auth
 The authentication directory for ser2net for admin connections.  The
 "ADMIN_CONNECTIONS" for more details.
-
+.TP
+.B mdns-interface: -1
+The default mDNS interface.
+.TP
+.B mdns-type: <NULL>
+The default mDNS type.
+.TP
+.B mdns-domain: <NULL>
+The default mDNS domain.
+.TP
+.B mdns-host: <NULL>
+The default mDNS host.
 .SH ADMIN CONNECTIONS
 There is an admin accepter that you can define for ser2net, it lets you
 log in, look at status, and change some things.  See "ADMIN INTERFACE"


Reply via email to