From 3863ab9af9ade586b5c2932842e88325f03583d2 Mon Sep 17 00:00:00 2001 From: Igor Goncharovsky <igor.goncharovsky@gmail.com> Date: Tue, 27 Aug 2019 17:10:56 +0600 Subject: [PATCH] chan_unistim: Fix clang warning: variable sized type not at end of a struct On reading information about initial client packet unistim use dirty implementation of destination ip address retrieval. This fix uses CMSG_*(..) to get ip address and make clang compile without warning. ASTERISK-25592 #close Reported-by: Alexander Traud Change-Id: Ic1fd34c2c2bcc951da65bf62e3f7a8adff8351b1 --- channels/chan_unistim.c | 49 ++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c index 539d935c0a..0ed190b444 100644 --- a/channels/chan_unistim.c +++ b/channels/chan_unistim.c @@ -1003,27 +1003,36 @@ static int get_to_address(int fd, struct sockaddr_in *toAddr) { #ifdef HAVE_PKTINFO int err; - struct msghdr msg; - struct { - struct cmsghdr cm; - int len; - struct in_addr address; - } ip_msg; - - /* Zero out the structures before we use them */ - /* This sets several key values to NULL */ - memset(&msg, 0, sizeof(msg)); - memset(&ip_msg, 0, sizeof(ip_msg)); - - /* Initialize the message structure */ - msg.msg_control = &ip_msg; - msg.msg_controllen = sizeof(ip_msg); + char cmbuf[0x100]; + struct cmsghdr *cmsg; + struct sockaddr_in peeraddr; + struct in_addr addr; + struct msghdr mh = { + .msg_name = &peeraddr, + .msg_namelen = sizeof(peeraddr), + .msg_control = cmbuf, + .msg_controllen = sizeof(cmbuf), + }; + memset(&addr, 0, sizeof(addr)); /* Get info about the incoming packet */ - err = recvmsg(fd, &msg, MSG_PEEK); + err = recvmsg(fd, &mh, MSG_PEEK); if (err == -1) { ast_log(LOG_WARNING, "recvmsg returned an error: %s\n", strerror(errno)); + return err; + } + for(cmsg = CMSG_FIRSTHDR(&mh); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&mh, cmsg)) + { + if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { + struct in_pktinfo *pkt = (struct in_pktinfo*)CMSG_DATA(cmsg); + addr = pkt->ipi_addr; + if (unistimdebug) { + ast_verb(0, "message received on address %s\n", ast_inet_ntoa(addr)); + } + } } - memcpy(&toAddr->sin_addr, &ip_msg.address, sizeof(struct in_addr)); + memcpy(&toAddr->sin_addr, &addr, sizeof(struct in_addr)); return err; #else memcpy(toAddr, &public_ip, sizeof(*toAddr)); @@ -1031,6 +1040,7 @@ static int get_to_address(int fd, struct sockaddr_in *toAddr) #endif } + /* Allocate memory & initialize structures for a new phone */ /* addr_from : ip address of the phone */ static struct unistimsession *create_client(const struct sockaddr_in *addr_from) @@ -1042,7 +1052,10 @@ static struct unistimsession *create_client(const struct sockaddr_in *addr_from) return NULL; memcpy(&s->sin, addr_from, sizeof(struct sockaddr_in)); - get_to_address(unistimsock, &s->sout); + if (get_to_address(unistimsock, &s->sout) < 0) { + ast_free(s); + return NULL; + } s->sout.sin_family = AF_INET; if (unistimdebug) { ast_verb(0, "Creating a new entry for the phone from %s received via server ip %s\n", -- GitLab