From b830719b392dc96fd7987fb3dfba31a92a6fa38b Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Wed, 6 Jan 2016 16:41:44 +0100 Subject: stream.c: Handle SCTP in osmo_stream_srv_recv() --- src/stream.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/stream.c b/src/stream.c index fd02b74..4b75e7f 100644 --- a/src/stream.c +++ b/src/stream.c @@ -639,9 +639,65 @@ void osmo_stream_srv_send(struct osmo_stream_srv *conn, struct msgb *msg) int osmo_stream_srv_recv(struct osmo_stream_srv *conn, struct msgb *msg) { +#ifdef HAVE_LIBSCTP + struct sctp_sndrcvinfo sinfo; + int flags = 0; +#endif int ret; - ret = recv(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), 0); + if (!msg) + return -EINVAL; + + switch (conn->srv->proto) { +#ifdef HAVE_LIBSCTP + case IPPROTO_SCTP: + ret = sctp_recvmsg(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), + NULL, NULL, &sinfo, &flags); + if (flags & MSG_NOTIFICATION) { + union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); + LOGP(DLINP, LOGL_DEBUG, "NOTIFICATION %u flags=0x%x\n", notif->sn_header.sn_type, notif->sn_header.sn_flags); + switch (notif->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + LOGP(DLINP, LOGL_DEBUG, "===> ASSOC CHANGE:"); + switch (notif->sn_assoc_change.sac_state) { + case SCTP_COMM_UP: + LOGPC(DLINP, LOGL_DEBUG, " UP\n"); + break; + case SCTP_COMM_LOST: + LOGPC(DLINP, LOGL_DEBUG, " LOST\n"); + break; + case SCTP_RESTART: + LOGPC(DLINP, LOGL_DEBUG, " RESTART\n"); + break; + case SCTP_SHUTDOWN_COMP: + LOGPC(DLINP, LOGL_DEBUG, " SHUTDOWN COMP\n"); + break; + case SCTP_CANT_STR_ASSOC: + LOGPC(DLINP, LOGL_DEBUG, " CANT STR ASSOC\n"); + break; + } + break; + case SCTP_PEER_ADDR_CHANGE: + LOGP(DLINP, LOGL_DEBUG, "===> PEER ADDR CHANGE\n"); + break; + case SCTP_SHUTDOWN_EVENT: + LOGP(DLINP, LOGL_DEBUG, "===> SHUTDOWN EVT\n"); + /* Handle this like a regular disconnect */ + return 0; + break; + } + return -EAGAIN; + } + msgb_sctp_ppid(msg) = ntohl(sinfo.sinfo_ppid); + msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + break; +#endif + case IPPROTO_TCP: + default: + ret = recv(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), 0); + break; + } + if (ret < 0) { if (errno == EPIPE || errno == ECONNRESET) { LOGP(DLINP, LOGL_ERROR, -- cgit v1.2.3