This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
pespin gerrit-no-reply at lists.osmocom.orgpespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-netif/+/26434 ) Change subject: stream: Add support for AF_UNIX sockets ...................................................................... stream: Add support for AF_UNIX sockets Change-Id: I5237a8121be05a9a31a39ca38a6a139062f258c4 --- M include/osmocom/netif/stream.h M src/stream.c 2 files changed, 223 insertions(+), 72 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/34/26434/1 diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 331dec1..b82dff1 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -25,6 +25,8 @@ int osmo_stream_srv_link_set_addrs(struct osmo_stream_srv_link *link, const char **addr, size_t addrcnt); void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port); void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto); +int osmo_stream_srv_link_set_type(struct osmo_stream_srv_link *link, int type); +int osmo_stream_srv_link_set_domain(struct osmo_stream_srv_link *link, int domain); void osmo_stream_srv_link_set_accept_cb(struct osmo_stream_srv_link *link, int (*accept_cb)(struct osmo_stream_srv_link *link, int fd)); void osmo_stream_srv_link_set_data(struct osmo_stream_srv_link *link, void *data); void *osmo_stream_srv_link_get_data(struct osmo_stream_srv_link *link); @@ -57,6 +59,8 @@ void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); int osmo_stream_cli_set_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt); void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port); +int osmo_stream_cli_set_type(struct osmo_stream_cli *cli, int type); +int osmo_stream_cli_set_domain(struct osmo_stream_cli *cli, int domain); void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto); void osmo_stream_cli_set_local_addr(struct osmo_stream_cli *cli, const char *addr); int osmo_stream_cli_set_local_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt); diff --git a/src/stream.c b/src/stream.c index 309aafe..1b3d0fb 100644 --- a/src/stream.c +++ b/src/stream.c @@ -256,6 +256,8 @@ char *local_addr[OSMO_STREAM_MAX_ADDRS]; uint8_t local_addrcnt; uint16_t local_port; + int sk_domain; + int sk_type; uint16_t proto; int (*connect_cb)(struct osmo_stream_cli *srv); int (*disconnect_cb)(struct osmo_stream_cli *srv); @@ -349,20 +351,26 @@ LOGSCLI(cli, LOGL_DEBUG, "sending %u bytes of data\n", msgb_length(msg)); - switch (cli->proto) { -#ifdef HAVE_LIBSCTP - case IPPROTO_SCTP: - memset(&sinfo, 0, sizeof(sinfo)); - sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); - sinfo.sinfo_stream = msgb_sctp_stream(msg); - ret = sctp_send(cli->ofd.fd, msg->data, msgb_length(msg), - &sinfo, MSG_NOSIGNAL); + switch (cli->sk_domain) { + case AF_UNIX: + ret = send(cli->ofd.fd, msg->data, msg->len, 0); break; -#endif - case IPPROTO_TCP: default: - ret = send(cli->ofd.fd, msg->data, msgb_length(msg), 0); - break; + switch (cli->proto) { +#ifdef HAVE_LIBSCTP + case IPPROTO_SCTP: + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); + sinfo.sinfo_stream = msgb_sctp_stream(msg); + ret = sctp_send(cli->ofd.fd, msg->data, msgb_length(msg), + &sinfo, MSG_NOSIGNAL); + break; +#endif + case IPPROTO_TCP: + default: + ret = send(cli->ofd.fd, msg->data, msgb_length(msg), 0); + break; + } } if (ret < 0) { if (errno == EPIPE || errno == ENOTCONN) { @@ -395,15 +403,20 @@ LOGSCLI(cli, LOGL_DEBUG, "connection done.\n"); cli->state = STREAM_CLI_STATE_CONNECTED; - if (cli->proto == IPPROTO_SCTP) { + switch (cli->sk_domain) { + case AF_UNIX: + break; + default: + if (cli->proto == IPPROTO_SCTP) { #ifdef SO_NOSIGPIPE - int val = 1; + int val = 1; - ret = setsockopt(ofd->fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&val, sizeof(val)); - if (ret < 0) - LOGSCLI(cli, LOGL_DEBUG, "Failed setting SO_NOSIGPIPE: %s\n", strerror(errno)); + ret = setsockopt(ofd->fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&val, sizeof(val)); + if (ret < 0) + LOGSCLI(cli, LOGL_DEBUG, "Failed setting SO_NOSIGPIPE: %s\n", strerror(errno)); #endif - sctp_sock_activate_events(ofd->fd); + sctp_sock_activate_events(ofd->fd); + } } if (cli->connect_cb) cli->connect_cb(cli); @@ -441,6 +454,8 @@ if (!cli) return NULL; + cli->sk_domain = AF_UNSPEC; + cli->sk_type = SOCK_STREAM; cli->proto = IPPROTO_TCP; cli->ofd.fd = -1; cli->ofd.priv_nr = 0; /* XXX */ @@ -557,6 +572,46 @@ cli->flags |= OSMO_STREAM_CLI_F_RECONF; } +/*! \brief Set the socket type for the stream server link + * \param[in] cli Stream Client to modify + * \param[in] type Socket Type (like SOCK_STREAM (default), SOCK_SEQPACKET, ...) + * \returns zero on success, negative on error. + */ +int osmo_stream_cli_set_type(struct osmo_stream_cli *cli, int type) +{ + switch (type) { + case SOCK_STREAM: + case SOCK_SEQPACKET: + break; + default: + return -ENOTSUP; + } + cli->sk_type = type; + cli->flags |= OSMO_STREAM_CLI_F_RECONF; + return 0; +} + +/*! \brief Set the socket type for the stream server link + * \param[in] cli Stream Client to modify + * \param[in] type Socket Domain (like AF_UNSPEC (default for IP), AF_UNIX, AF_INET, ...) + * \returns zero on success, negative on error. + */ +int osmo_stream_cli_set_domain(struct osmo_stream_cli *cli, int domain) +{ + switch (domain) { + case AF_UNSPEC: + case AF_INET: + case AF_INET6: + case AF_UNIX: + break; + default: + return -ENOTSUP; + } + cli->sk_domain = domain; + cli->flags |= OSMO_STREAM_CLI_F_RECONF; + return 0; +} + /*! \brief Set the reconnect time of the stream client socket * \param[in] cli Stream Client to modify * \param[in] timeout Re-connect timeout in seconds or negative value to disable auto-reconnection */ @@ -731,21 +786,29 @@ cli->flags &= ~OSMO_STREAM_CLI_F_RECONF; - - switch (cli->proto) { -#ifdef HAVE_LIBSCTP - case IPPROTO_SCTP: - ret = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, cli->proto, - (const char **)cli->local_addr, cli->local_addrcnt, cli->local_port, - (const char **)cli->addr, cli->addrcnt, cli->port, - OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); + switch (cli->sk_domain) { + case AF_UNIX: + ret = osmo_sock_unix_init(cli->sk_type, 0, cli->addr[0], OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); break; -#endif + case AF_INET: + case AF_INET6: + case AF_UNSPEC: default: - ret = osmo_sock_init2(AF_UNSPEC, SOCK_STREAM, cli->proto, - cli->local_addr[0], cli->local_port, - cli->addr[0], cli->port, - OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); + switch (cli->proto) { +#ifdef HAVE_LIBSCTP + case IPPROTO_SCTP: + ret = osmo_sock_init2_multiaddr(cli->sk_domain, cli->sk_type, cli->proto, + (const char **)cli->local_addr, cli->local_addrcnt, cli->local_port, + (const char **)cli->addr, cli->addrcnt, cli->port, + OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); + break; +#endif + default: + ret = osmo_sock_init2(cli->sk_domain, cli->sk_type, cli->proto, + cli->local_addr[0], cli->local_port, + cli->addr[0], cli->port, + OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); + } } if (ret < 0) { @@ -827,6 +890,8 @@ char *addr[OSMO_STREAM_MAX_ADDRS]; uint8_t addrcnt; uint16_t port; + int sk_domain; + int sk_type; uint16_t proto; int (*accept_cb)(struct osmo_stream_srv_link *srv, int fd); void *data; @@ -838,7 +903,7 @@ int ret; int sock_fd; char addrstr[128]; - bool is_ipv6; + bool is_ipv6 = false; struct sockaddr_storage sa; socklen_t sa_len = sizeof(sa); struct osmo_stream_srv_link *link = ofd->data; @@ -849,19 +914,35 @@ "peer, reason=`%s'\n", strerror(errno)); return ret; } - is_ipv6 = ((struct sockaddr *)&sa)->sa_family == AF_INET6; - LOGP(DLINP, LOGL_DEBUG, "accept()ed new link from %s to port %u\n", - inet_ntop(is_ipv6 ? AF_INET6 : AF_INET, - is_ipv6 ? (void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr) : - (void*)&(((struct sockaddr_in *)&sa)->sin_addr), - addrstr, sizeof(addrstr)), - link->port); sock_fd = ret; - if (link->proto == IPPROTO_SCTP) { - ret = sctp_sock_activate_events(sock_fd); - if (ret < 0) - goto error_close_socket; + is_ipv6 = false; + switch (((struct sockaddr *)&sa)->sa_family) { + case AF_UNIX: + LOGP(DLINP, LOGL_DEBUG, "accept()ed new link on fd %d\n", + sock_fd); + break; + case AF_INET6: + is_ipv6 = true; + /* fall through */ + case AF_INET: + LOGP(DLINP, LOGL_DEBUG, "accept()ed new link from %s to port %u\n", + inet_ntop(is_ipv6 ? AF_INET6 : AF_INET, + is_ipv6 ? (void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr) : + (void*)&(((struct sockaddr_in *)&sa)->sin_addr), + addrstr, sizeof(addrstr)), + link->port); + + if (link->proto == IPPROTO_SCTP) { + ret = sctp_sock_activate_events(sock_fd); + if (ret < 0) + goto error_close_socket; + } + break; + default: + LOGP(DLINP, LOGL_DEBUG, "accept()ed unexpected address family %d\n", + ((struct sockaddr *)&sa)->sa_family); + goto error_close_socket; } if (link->flags & OSMO_STREAM_SRV_F_NODELAY) { @@ -899,6 +980,8 @@ if (!link) return NULL; + link->sk_domain = AF_UNSPEC; + link->sk_type = SOCK_STREAM; link->proto = IPPROTO_TCP; osmo_fd_setup(&link->ofd, -1, OSMO_FD_READ | OSMO_FD_WRITE, osmo_stream_srv_fd_cb, link, 0); @@ -978,6 +1061,47 @@ link->flags |= OSMO_STREAM_SRV_F_RECONF; } + +/*! \brief Set the socket type for the stream server link + * \param[in] link Stream Server Link to modify + * \param[in] type Socket Type (like SOCK_STREAM (default), SOCK_SEQPACKET, ...) + * \returns zero on success, negative on error. + */ +int osmo_stream_srv_link_set_type(struct osmo_stream_srv_link *link, int type) +{ + switch (type) { + case SOCK_STREAM: + case SOCK_SEQPACKET: + break; + default: + return -ENOTSUP; + } + link->sk_type = type; + link->flags |= OSMO_STREAM_SRV_F_RECONF; + return 0; +} + +/*! \brief Set the socket type for the stream server link + * \param[in] link Stream Server Link to modify + * \param[in] type Socket Domain (like AF_UNSPEC (default for IP), AF_UNIX, AF_INET, ...) + * \returns zero on success, negative on error. + */ +int osmo_stream_srv_link_set_domain(struct osmo_stream_srv_link *link, int domain) +{ + switch (domain) { + case AF_UNSPEC: + case AF_INET: + case AF_INET6: + case AF_UNIX: + break; + default: + return -ENOTSUP; + } + link->sk_domain = domain; + link->flags |= OSMO_STREAM_SRV_F_RECONF; + return 0; +} + /*! \brief Set application private data of the stream server link * \param[in] link Stream Server Link to modify * \param[in] data User-specific data (available in call-back functions) */ @@ -1060,17 +1184,28 @@ link->flags &= ~OSMO_STREAM_SRV_F_RECONF; - switch (link->proto) { + switch (link->sk_domain) { + case AF_UNIX: + ret = osmo_sock_unix_init(link->sk_type, 0, link->addr[0], OSMO_SOCK_F_BIND); + break; + case AF_UNSPEC: + case AF_INET: + case AF_INET6: + switch (link->proto) { #ifdef HAVE_LIBSCTP - case IPPROTO_SCTP: - ret = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, link->proto, - (const char **)link->addr, link->addrcnt, link->port, - NULL, 0, 0, OSMO_SOCK_F_BIND); - break; + case IPPROTO_SCTP: + ret = osmo_sock_init2_multiaddr(link->sk_domain, link->sk_type, link->proto, + (const char **)link->addr, link->addrcnt, link->port, + NULL, 0, 0, OSMO_SOCK_F_BIND); + break; #endif - default: - ret = osmo_sock_init(AF_UNSPEC, SOCK_STREAM, link->proto, - link->addr[0], link->port, OSMO_SOCK_F_BIND); + default: + ret = osmo_sock_init(link->sk_domain, link->sk_type, link->proto, + link->addr[0], link->port, OSMO_SOCK_F_BIND); + } + break; + default: + ret = -ENOTSUP; } if (ret < 0) return ret; @@ -1144,20 +1279,26 @@ llist_del(lh); msg = llist_entry(lh, struct msgb, list); - switch (conn->srv->proto) { -#ifdef HAVE_LIBSCTP - case IPPROTO_SCTP: - memset(&sinfo, 0, sizeof(sinfo)); - sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); - sinfo.sinfo_stream = msgb_sctp_stream(msg); - ret = sctp_send(conn->ofd.fd, msg->data, msgb_length(msg), - &sinfo, MSG_NOSIGNAL); - break; -#endif - case IPPROTO_TCP: - default: + switch (conn->srv->sk_domain) { + case AF_UNIX: ret = send(conn->ofd.fd, msg->data, msg->len, 0); break; + default: + switch (conn->srv->proto) { +#ifdef HAVE_LIBSCTP + case IPPROTO_SCTP: + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); + sinfo.sinfo_stream = msgb_sctp_stream(msg); + ret = sctp_send(conn->ofd.fd, msg->data, msgb_length(msg), + &sinfo, MSG_NOSIGNAL); + break; +#endif + case IPPROTO_TCP: + default: + ret = send(conn->ofd.fd, msg->data, msg->len, 0); + break; + } } if (ret < 0) { LOGP(DLINP, LOGL_ERROR, "error to send\n"); @@ -1352,16 +1493,22 @@ if (!msg) return -EINVAL; - switch (conn->srv->proto) { -#ifdef HAVE_LIBSCTP - case IPPROTO_SCTP: - ret = _sctp_recvmsg_wrapper(conn->ofd.fd, msg); - break; -#endif - case IPPROTO_TCP: - default: + switch (conn->srv->sk_domain) { + case AF_UNIX: ret = recv(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), 0); break; + default: + switch (conn->srv->proto) { +#ifdef HAVE_LIBSCTP + case IPPROTO_SCTP: + ret = _sctp_recvmsg_wrapper(conn->ofd.fd, msg); + break; +#endif + case IPPROTO_TCP: + default: + ret = recv(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), 0); + break; + } } if (ret < 0) { -- To view, visit https://gerrit.osmocom.org/c/libosmo-netif/+/26434 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Change-Id: I5237a8121be05a9a31a39ca38a6a139062f258c4 Gerrit-Change-Number: 26434 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pespin at sysmocom.de> Gerrit-Reviewer: Arran Cudbard-bell <a.cudbardb at freeradius.org> Gerrit-Reviewer: daniel <dwillmann at sysmocom.de> Gerrit-Reviewer: laforge <laforge at osmocom.org> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211201/820746e1/attachment.htm>