The previous behaviour was to assume a stale socket under the above
conditions and re-initialize the transport. Now the socket is checked
using getsockopt() and the transport re-initialized in case of an error.
UDP and UDP6 implementations are untested.
Signed-off-by: Delio Brignoli <***@audioscience.com>
---
port.c | 13 +++++++++++--
raw.c | 12 ++++++++++++
transport.c | 5 +++++
transport.h | 2 ++
transport_private.h | 2 ++
udp.c | 12 ++++++++++++
udp6.c | 12 ++++++++++++
7 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/port.c b/port.c
index 6644685..65f45d6 100644
--- a/port.c
+++ b/port.c
@@ -1331,6 +1331,14 @@ static int port_renew_transport(struct port *p)
return 0;
}
+static int port_check_transport(struct port *p)
+{
+ if (!port_is_enabled(p)) {
+ return 0;
+ }
+ return transport_check(p->trp, &p->fda);;
+}
+
/*
* Returns non-zero if the announce message is different than last.
*/
@@ -1991,8 +1999,9 @@ enum fsm_event port_event(struct port *p, int fd_index)
if (p->best)
fc_clear(p->best);
port_set_announce_tmo(p);
- if (clock_slave_only(p->clock) && port_renew_transport(p)) {
- return EV_FAULT_DETECTED;
+ if (clock_slave_only(p->clock) && port_check_transport(p)) {
+ if (port_renew_transport(p))
+ return EV_FAULT_DETECTED;
}
return EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES;
diff --git a/raw.c b/raw.c
index 326ccd2..18bae2c 100644
--- a/raw.c
+++ b/raw.c
@@ -138,6 +138,17 @@ static int raw_configure(int fd, int event, int index,
return -1;
}
+static int raw_check(struct transport *t, struct fdarray *fda)
+{
+ int sockerror = 0;
+ socklen_t len = sizeof(sockerror);
+ int err1 = getsockopt(fda->fd[FD_EVENT], SOL_SOCKET, SO_ERROR,
+ &sockerror, &len);
+ int err2 = getsockopt(fda->fd[FD_GENERAL], SOL_SOCKET, SO_ERROR,
+ &sockerror, &len);
+ return err1 || err2;
+}
+
static int raw_close(struct transport *t, struct fdarray *fda)
{
close(fda->fd[0]);
@@ -315,6 +326,7 @@ struct transport *raw_transport_create(void)
raw = calloc(1, sizeof(*raw));
if (!raw)
return NULL;
+ raw->t.check = raw_check;
raw->t.close = raw_close;
raw->t.open = raw_open;
raw->t.recv = raw_recv;
diff --git a/transport.c b/transport.c
index 3c70b2b..8af2f9d 100644
--- a/transport.c
+++ b/transport.c
@@ -24,6 +24,11 @@
#include "udp6.h"
#include "uds.h"
+int transport_check(struct transport *t, struct fdarray *fda)
+{
+ return t->check(t, fda);
+}
+
int transport_close(struct transport *t, struct fdarray *fda)
{
return t->close(t, fda);
diff --git a/transport.h b/transport.h
index 46af456..8581436 100644
--- a/transport.h
+++ b/transport.h
@@ -61,6 +61,8 @@ struct hw_timestamp {
struct transport;
+int transport_check(struct transport *t, struct fdarray *fda);
+
int transport_close(struct transport *t, struct fdarray *fda);
int transport_open(struct transport *t, char *name,
diff --git a/transport_private.h b/transport_private.h
index 0c553e1..5fca9f2 100644
--- a/transport_private.h
+++ b/transport_private.h
@@ -28,6 +28,8 @@
struct transport {
enum transport_type type;
+ int (*check)(struct transport *t, struct fdarray *fda);
+
int (*close)(struct transport *t, struct fdarray *fda);
int (*open)(struct transport *t, char *name, struct fdarray *fda,
diff --git a/udp.c b/udp.c
index fea0122..6274a31 100644
--- a/udp.c
+++ b/udp.c
@@ -86,6 +86,17 @@ static int mcast_join(int fd, int index, const struct sockaddr *grp,
return 0;
}
+static int udp_check(struct transport *t, struct fdarray *fda)
+{
+ int sockerror = 0;
+ socklen_t len = sizeof(sockerror);
+ int err1 = getsockopt(fda->fd[FD_EVENT], SOL_SOCKET, SO_ERROR,
+ &sockerror, &len);
+ int err2 = getsockopt(fda->fd[FD_GENERAL], SOL_SOCKET, SO_ERROR,
+ &sockerror, &len);
+ return err1 || err2;
+}
+
static int udp_close(struct transport *t, struct fdarray *fda)
{
close(fda->fd[0]);
@@ -256,6 +267,7 @@ struct transport *udp_transport_create(void)
struct udp *udp = calloc(1, sizeof(*udp));
if (!udp)
return NULL;
+ udp->t.check = udp_check;
udp->t.close = udp_close;
udp->t.open = udp_open;
udp->t.recv = udp_recv;
diff --git a/udp6.c b/udp6.c
index 2cb0179..a3ea6e5 100644
--- a/udp6.c
+++ b/udp6.c
@@ -93,6 +93,17 @@ static int mc_join(int fd, int index, const struct sockaddr *grp, socklen_t grpl
return 0;
}
+static int udp6_check(struct transport *t, struct fdarray *fda)
+{
+ int sockerror = 0;
+ socklen_t len = sizeof(sockerror);
+ int err1 = getsockopt(fda->fd[FD_EVENT], SOL_SOCKET, SO_ERROR,
+ &sockerror, &len);
+ int err2 = getsockopt(fda->fd[FD_GENERAL], SOL_SOCKET, SO_ERROR,
+ &sockerror, &len);
+ return err1 || err2;
+}
+
static int udp6_close(struct transport *t, struct fdarray *fda)
{
close(fda->fd[0]);
@@ -268,6 +279,7 @@ struct transport *udp6_transport_create(void)
udp6 = calloc(1, sizeof(*udp6));
if (!udp6)
return NULL;
+ udp6->t.check = udp6_check;
udp6->t.close = udp6_close;
udp6->t.open = udp6_open;
udp6->t.recv = udp6_recv;
--
1.7.0.4