diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2019-03-27 23:18:25 +0100 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2024-07-05 17:07:14 +0200 |
commit | e5fc2e6a0233ce375eb5c6cc94657ab7d66be4ad (patch) | |
tree | 0d8a39d58fe8b82e421fe6737d2471d2f3cdcedb | |
parent | 08ff0af8986099e6fb1d8a94c7ce62c83e4df7f1 (diff) |
Unix: Implement sk_connect_unix
Support abstract socket in sk_unix_connect
Implement SK_UNIX_ACTIVE
-rw-r--r-- | lib/socket.h | 1 | ||||
-rw-r--r-- | sysdep/unix/io.c | 59 | ||||
-rw-r--r-- | sysdep/unix/unix.h | 1 |
3 files changed, 61 insertions, 0 deletions
diff --git a/lib/socket.h b/lib/socket.h index 3417423f..7551aa81 100644 --- a/lib/socket.h +++ b/lib/socket.h @@ -147,6 +147,7 @@ extern int sk_priority_control; /* Suggested priority for control traffic, shou #define SK_UNIX 9 #define SK_SSH_ACTIVE 10 /* - - * * - ? - DA = host */ #define SK_SSH 11 +#define SK_UNIX_ACTIVE 12 /* * Socket subtypes diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index ba2e1661..892226e8 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -1089,6 +1089,14 @@ sk_tcp_connected(sock *s) s->tx_hook(s); } +static void +sk_unix_connected(sock *s) +{ + sk_alloc_bufs(s); + s->type = SK_UNIX; + s->tx_hook(s); +} + #ifdef HAVE_LIBSSH static void sk_ssh_connected(sock *s) @@ -1562,6 +1570,51 @@ sk_open_unix(sock *s, const char *name) return 0; } +int +sk_connect_unix(sock *s, const char *name, socklen_t namelen) +{ + struct sockaddr_un sa; + int fd; + + if (namelen > sizeof(sa.sun_path)) + return -1; + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) + return -1; + + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) + { + close(fd); + return -3; + } + + /* Path length checked in test_old_bird() */ + memset(&sa, 0, sizeof(sa)); + sa.sun_family = AF_UNIX; + memcpy(sa.sun_path, name, namelen); + + s->fd = fd; + s->type = SK_UNIX_ACTIVE; + s->ttx = ""; /* Force s->ttx != s->tpos */ + + if (connect(fd, (struct sockaddr *) &sa, sizeof(sa.sun_family) + namelen) >= 0) + sk_unix_connected(s); + else if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS && + errno != ECONNREFUSED && errno != EHOSTUNREACH && errno != ENETUNREACH) + { + ERR2("connect"); + } + + sk_insert(s); + return 0; + + err: + close(fd); + s->fd = -1; + return -1; +} + #define CMSG_RX_SPACE MAX(CMSG4_SPACE_PKTINFO+CMSG4_SPACE_TTL, \ CMSG6_SPACE_PKTINFO+CMSG6_SPACE_TTL) @@ -1985,6 +2038,12 @@ sk_write_noflush(sock *s) return 0; } + case SK_UNIX_ACTIVE: + { + sk_unix_connected(s); + return 0; + } + #ifdef HAVE_LIBSSH case SK_SSH_ACTIVE: { diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h index 33ece06c..d0cebbcc 100644 --- a/sysdep/unix/unix.h +++ b/sysdep/unix/unix.h @@ -108,6 +108,7 @@ void io_init(void); void io_loop(void); void io_log_dump(void); int sk_open_unix(struct birdsock *s, const char *name); +int sk_connect_unix(struct birdsock *s, const char *name, socklen_t namelen); struct rfile *rf_open(struct pool *, const char *name, const char *mode); struct rfile *rf_fdopen(pool *p, int fd, const char *mode); void *rf_file(struct rfile *f); |