Coverage Report

Created: 2025-11-09 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rtpproxy/src/rtpp_network_io.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2004-2006 Maxim Sobolev <sobomax@FreeBSD.org>
3
 * Copyright (c) 2006-2019 Sippy Software, Inc., http://www.sippysoft.com
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
 * SUCH DAMAGE.
26
 *
27
 */
28
29
#include <sys/types.h>
30
#include <sys/socket.h>
31
#include <string.h>
32
#include <netinet/in.h>
33
34
#include "config_pp.h"
35
36
#include "rtpp_types.h"
37
#include "rtpp_network.h"
38
#include "rtpp_network_io.h"
39
40
static ssize_t
41
_recvfromto(int s, void *buf, size_t len, struct sockaddr *from,
42
  socklen_t *fromlen, struct sockaddr *to, socklen_t *tolen,
43
  void *tp, size_t tplen, int mtype)
44
0
{
45
    /* We use a union to make sure hdr is aligned */
46
0
    union {
47
0
        struct cmsghdr hdr;
48
0
        unsigned char buf[CMSG_SPACE(1024)];
49
0
    } cmsgbuf;
50
0
#if !defined(IP_RECVDSTADDR)
51
0
    struct in_pktinfo *pktinfo;
52
0
#endif
53
0
    struct cmsghdr *cmsg;
54
0
    struct msghdr msg;
55
0
    struct iovec iov;
56
0
    ssize_t rval;
57
58
0
    memset(&msg, '\0', sizeof(msg));
59
0
    iov.iov_base = buf;
60
0
    iov.iov_len = len;
61
0
    msg.msg_name = from;
62
0
    msg.msg_namelen = *fromlen;
63
0
    msg.msg_iov = &iov;
64
0
    msg.msg_iovlen = 1;
65
0
    msg.msg_control = cmsgbuf.buf;
66
0
    msg.msg_controllen = sizeof(cmsgbuf.buf);
67
68
0
    rval = recvmsg(s, &msg, 0);
69
0
    if (rval < 0)
70
0
        return (rval);
71
72
0
    *tolen = 0;
73
0
    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
74
0
      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
75
#if defined(IP_RECVDSTADDR)
76
        if (cmsg->cmsg_level == IPPROTO_IP &&
77
          cmsg->cmsg_type == IP_RECVDSTADDR) {
78
            memcpy(&satosin(to)->sin_addr, CMSG_DATA(cmsg),
79
              sizeof(struct in_addr));
80
            to->sa_family = AF_INET;
81
            *tolen = sizeof(struct sockaddr_in);
82
            break;
83
        }
84
#else
85
0
        if (cmsg->cmsg_level == SOL_IP &&
86
0
          cmsg->cmsg_type == IP_PKTINFO) {
87
0
            pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
88
0
            memcpy(&satosin(to)->sin_addr, &pktinfo->ipi_addr,
89
0
              sizeof(struct in_addr));
90
0
            to->sa_family = AF_INET;
91
0
            *tolen = sizeof(struct sockaddr_in);
92
0
            break;
93
0
        }
94
0
#endif
95
0
        if ((cmsg->cmsg_level == SOL_SOCKET) &&
96
0
          (cmsg->cmsg_type == mtype)) {
97
0
            memcpy(tp, CMSG_DATA(cmsg), tplen);
98
0
        }
99
0
    }
100
0
    *fromlen = msg.msg_namelen;
101
0
    return (rval);
102
0
}
103
104
ssize_t
105
recvfromto(int s, void *buf, size_t len, struct sockaddr *from,
106
  socklen_t *fromlen, struct sockaddr *to, socklen_t *tolen,
107
  struct timespec *timeptr)
108
0
{
109
0
    ssize_t r;
110
0
    struct timeval rtime = {0};
111
112
0
    r = _recvfromto(s, buf, len, from, fromlen, to, tolen, &rtime,
113
0
      sizeof(rtime), SCM_TIMESTAMP);
114
0
    if (r >= 0) {
115
0
        timeptr->tv_sec = rtime.tv_sec;
116
0
        timeptr->tv_nsec = rtime.tv_usec * 1000;
117
0
    }
118
0
    return (r);
119
0
}
120
121
#if HAVE_SO_TS_CLOCK
122
ssize_t
123
recvfromto_mono(int s, void *buf, size_t len, struct sockaddr *from,
124
  socklen_t *fromlen, struct sockaddr *to, socklen_t *tolen,
125
  struct timespec *timeptr)
126
{
127
128
    return (_recvfromto(s, buf, len, from, fromlen, to, tolen, timeptr,
129
      sizeof(*timeptr), SCM_MONOTONIC));
130
}
131
#endif /* HAVE_SO_TS_CLOCK */