]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_unistim: Fix clang warning: variable sized type not at end of a struct
authorIgor Goncharovsky <igor.goncharovsky@gmail.com>
Tue, 27 Aug 2019 11:10:56 +0000 (17:10 +0600)
committerIgor Goncharovsky <igor.goncharovsky@gmail.com>
Wed, 4 Sep 2019 03:59:52 +0000 (22:59 -0500)
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

index 539d935c0a4732836475ec1b44fa252c71c7ca35..0ed190b444782fb8032a95fd933cb8f7aa0d889b 100644 (file)
@@ -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",