tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rtp.c (6553B)


      1 /*
      2 * rtp.c
      3 *
      4 * library functions for the real-time transport protocol
      5 *
      6 * David A. McGrew
      7 * Cisco Systems, Inc.
      8 */
      9 
     10 /*
     11 *
     12 * Copyright (c) 2001-2017, Cisco Systems, Inc.
     13 * All rights reserved.
     14 *
     15 * Redistribution and use in source and binary forms, with or without
     16 * modification, are permitted provided that the following conditions
     17 * are met:
     18 *
     19 *   Redistributions of source code must retain the above copyright
     20 *   notice, this list of conditions and the following disclaimer.
     21 *
     22 *   Redistributions in binary form must reproduce the above
     23 *   copyright notice, this list of conditions and the following
     24 *   disclaimer in the documentation and/or other materials provided
     25 *   with the distribution.
     26 *
     27 *   Neither the name of the Cisco Systems, Inc. nor the names of its
     28 *   contributors may be used to endorse or promote products derived
     29 *   from this software without specific prior written permission.
     30 *
     31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     34 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     35 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     36 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     42 * OF THE POSSIBILITY OF SUCH DAMAGE.
     43 *
     44 */
     45 
     46 #include "rtp.h"
     47 
     48 #include <stdio.h>
     49 #include <string.h>
     50 
     51 #include <sys/types.h>
     52 #ifdef HAVE_SYS_SOCKET_H
     53 #include <sys/socket.h>
     54 #endif
     55 
     56 #include "cipher_priv.h"
     57 
     58 #define PRINT_DEBUG 0   /* set to 1 to print out debugging data */
     59 #define VERBOSE_DEBUG 0 /* set to 1 to print out more data      */
     60 
     61 int rtp_sendto(rtp_sender_t sender, const void *msg, int len)
     62 {
     63    int octets_sent;
     64    srtp_err_status_t stat;
     65    int pkt_len = len + RTP_HEADER_LEN;
     66 
     67    /* marshal data */
     68    strncpy(sender->message.body, msg, len);
     69 
     70    /* update header */
     71    sender->message.header.seq = ntohs(sender->message.header.seq) + 1;
     72    sender->message.header.seq = htons(sender->message.header.seq);
     73    sender->message.header.ts = ntohl(sender->message.header.ts) + 1;
     74    sender->message.header.ts = htonl(sender->message.header.ts);
     75 
     76    /* apply srtp */
     77    stat = srtp_protect(sender->srtp_ctx, &sender->message.header, &pkt_len);
     78    if (stat) {
     79 #if PRINT_DEBUG
     80        fprintf(stderr, "error: srtp protection failed with code %d\n", stat);
     81 #endif
     82        return -1;
     83    }
     84 #if VERBOSE_DEBUG
     85    srtp_print_packet(&sender->message.header, pkt_len);
     86 #endif
     87    octets_sent =
     88        sendto(sender->socket, (void *)&sender->message, pkt_len, 0,
     89               (struct sockaddr *)&sender->addr, sizeof(struct sockaddr_in));
     90 
     91    if (octets_sent != pkt_len) {
     92 #if PRINT_DEBUG
     93        fprintf(stderr, "error: couldn't send message %s", (char *)msg);
     94        perror("");
     95 #endif
     96    }
     97 
     98    return octets_sent;
     99 }
    100 
    101 int rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len)
    102 {
    103    int octets_recvd;
    104    srtp_err_status_t stat;
    105 
    106    octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message, *len,
    107                            0, (struct sockaddr *)NULL, 0);
    108 
    109    if (octets_recvd == -1) {
    110        *len = 0;
    111        return -1;
    112    }
    113 
    114    /* verify rtp header */
    115    if (receiver->message.header.version != 2) {
    116        *len = 0;
    117        return -1;
    118    }
    119 
    120 #if PRINT_DEBUG
    121    fprintf(stderr, "%d octets received from SSRC %u\n", octets_recvd,
    122            receiver->message.header.ssrc);
    123 #endif
    124 #if VERBOSE_DEBUG
    125    srtp_print_packet(&receiver->message.header, octets_recvd);
    126 #endif
    127 
    128    /* apply srtp */
    129    stat = srtp_unprotect(receiver->srtp_ctx, &receiver->message.header,
    130                          &octets_recvd);
    131    if (stat) {
    132        fprintf(stderr, "error: srtp unprotection failed with code %d%s\n",
    133                stat,
    134                stat == srtp_err_status_replay_fail ? " (replay check failed)"
    135                : stat == srtp_err_status_auth_fail ? " (auth check failed)"
    136                                                    : "");
    137        return -1;
    138    }
    139    strncpy(msg, receiver->message.body, octets_recvd);
    140 
    141    return octets_recvd;
    142 }
    143 
    144 int rtp_sender_init(rtp_sender_t sender,
    145                    int sock,
    146                    struct sockaddr_in addr,
    147                    unsigned int ssrc)
    148 {
    149    /* set header values */
    150    sender->message.header.ssrc = htonl(ssrc);
    151    sender->message.header.ts = 0;
    152    sender->message.header.seq = (uint16_t)srtp_cipher_rand_u32_for_tests();
    153    sender->message.header.m = 0;
    154    sender->message.header.pt = 0x1;
    155    sender->message.header.version = 2;
    156    sender->message.header.p = 0;
    157    sender->message.header.x = 0;
    158    sender->message.header.cc = 0;
    159 
    160    /* set other stuff */
    161    sender->socket = sock;
    162    sender->addr = addr;
    163 
    164    return 0;
    165 }
    166 
    167 int rtp_receiver_init(rtp_receiver_t rcvr,
    168                      int sock,
    169                      struct sockaddr_in addr,
    170                      unsigned int ssrc)
    171 {
    172    /* set header values */
    173    rcvr->message.header.ssrc = htonl(ssrc);
    174    rcvr->message.header.ts = 0;
    175    rcvr->message.header.seq = 0;
    176    rcvr->message.header.m = 0;
    177    rcvr->message.header.pt = 0x1;
    178    rcvr->message.header.version = 2;
    179    rcvr->message.header.p = 0;
    180    rcvr->message.header.x = 0;
    181    rcvr->message.header.cc = 0;
    182 
    183    /* set other stuff */
    184    rcvr->socket = sock;
    185    rcvr->addr = addr;
    186 
    187    return 0;
    188 }
    189 
    190 int rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy)
    191 {
    192    return srtp_create(&sender->srtp_ctx, policy);
    193 }
    194 
    195 int rtp_sender_deinit_srtp(rtp_sender_t sender)
    196 {
    197    return srtp_dealloc(sender->srtp_ctx);
    198 }
    199 
    200 int rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy)
    201 {
    202    return srtp_create(&sender->srtp_ctx, policy);
    203 }
    204 
    205 int rtp_receiver_deinit_srtp(rtp_receiver_t sender)
    206 {
    207    return srtp_dealloc(sender->srtp_ctx);
    208 }
    209 
    210 rtp_sender_t rtp_sender_alloc(void)
    211 {
    212    return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t));
    213 }
    214 
    215 void rtp_sender_dealloc(rtp_sender_t rtp_ctx)
    216 {
    217    free(rtp_ctx);
    218 }
    219 
    220 rtp_receiver_t rtp_receiver_alloc(void)
    221 {
    222    return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t));
    223 }
    224 
    225 void rtp_receiver_dealloc(rtp_receiver_t rtp_ctx)
    226 {
    227    free(rtp_ctx);
    228 }