util.h 6.27 KB
Newer Older
1 2 3
/*****************************************************************************
 * util.h: Utils for the multicat suite
 *****************************************************************************
4
 * Copyright (C) 2009, 2011, 2014-2016 VideoLAN
5
 * $Id$
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * Authors: Christophe Massiot <massiot@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

24 25 26
#include <netinet/udp.h>
#include <netinet/ip.h>

27
#if defined(__APPLE__) || defined(__FreeBSD__)
28
#define POLLRDHUP 0
29 30 31 32
/* uClibc may does not have clock_nanosleep() */
#elif !defined (__UCLIBC__) || \
       defined (__UCLIBC__) && defined (__UCLIBC_HAS_THREADS_NATIVE__) \
                            && defined (__UCLIBC_HAS_ADVANCED_REALTIME__)
33
#define HAVE_CLOCK_NANOSLEEP
34
#endif
35 36 37

#define DEFAULT_PORT 1234
#define DEFAULT_PAYLOAD_SIZE 1316
38
#define DEFAULT_ROTATE_SIZE UINT64_C(97200000000)
39
#define DEFAULT_ROTATE_OFFSET UINT64_C(0)
40 41 42 43 44 45 46
#define TS_SIZE 188
#define RTP_HEADER_SIZE 12

#define VERB_DBG  3
#define VERB_INFO 2
#define VERB_WARN 1

47 48 49 50 51 52 53 54 55 56 57
/*****************************************************************************
 * sockaddr_t: wrapper to avoid strict-aliasing issues
 *****************************************************************************/
typedef union
{
    struct sockaddr_storage ss;
    struct sockaddr so;
    struct sockaddr_in sin;
    struct sockaddr_in6 sin6;
} sockaddr_t;

58 59 60 61
/*****************************************************************************
 * Raw udp packet structure with flexible-array payload
 *****************************************************************************/
struct udprawpkt {
62 63 64 65
#if !defined(__APPLE__)
#if defined(__FreeBSD__)
    struct  ip iph;
#else
66
    struct  iphdr iph;
67
#endif
68
    struct  udphdr udph;
69
#endif
70
    uint8_t payload[];
71 72 73 74 75 76 77 78
} __attribute__((packed));


/*****************************************************************************
 * OpenSocket options
 *****************************************************************************/
 struct opensocket_opt {
    struct udprawpkt *p_raw_pktheader;
79
    bool *pb_multicast;
80 81 82
 };


83 84 85
/*****************************************************************************
 * Prototypes
 *****************************************************************************/
86 87
void msg_Openlog( const char *ident, int option, int facility );
void msg_Closelog( void );
88 89 90 91 92 93 94
void msg_Info( void *_unused, const char *psz_format, ... );
void msg_Err( void *_unused, const char *psz_format, ... );
void msg_Warn( void *_unused, const char *psz_format, ... );
void msg_Dbg( void *_unused, const char *psz_format, ... );
void msg_Raw( void *_unused, const char *psz_format, ... );
uint64_t wall_Date( void );
void wall_Sleep( uint64_t i_delay );
95 96
uint64_t real_Date( void );
void real_Sleep( uint64_t i_delay );
97
int OpenSocket( const char *_psz_arg, int i_ttl, uint16_t i_bind_port,
98 99
                uint16_t i_connect_port, unsigned int *pi_weight, bool *pb_tcp,
                struct opensocket_opt *p_opt);
100 101 102
mode_t StatFile(const char *psz_arg);
int OpenFile( const char *psz_arg, bool b_read, bool b_append );
char *GetAuxFile( const char *psz_arg, size_t i_payload_size );
103
FILE *OpenAuxFile( const char *psz_arg, bool b_read, bool b_append );
104
off_t LookupAuxFile( const char *psz_arg, int64_t i_wanted, bool b_absolute );
105 106
void CheckFileSizes( const char *psz_file, const char *psz_aux_file,
                     size_t i_payload_size );
107 108
uint64_t GetDirFile( uint64_t i_rotate_size, uint64_t i_rotate_offset,
                     int64_t i_wanted );
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
int OpenDirFile( const char *psz_dir_path, uint64_t i_file, bool b_read,
                 size_t i_payload_size, FILE **pp_aux_file );
off_t LookupDirAuxFile( const char *psz_dir_path, uint64_t i_file,
                        int64_t i_wanted, size_t i_payload_size );

/*****************************************************************************
 * Aux files helpers
 *****************************************************************************/
static inline uint64_t FromSTC( const uint8_t *p_aux )
{
    return ((uint64_t)p_aux[0] << 56)
         | ((uint64_t)p_aux[1] << 48)
         | ((uint64_t)p_aux[2] << 40)
         | ((uint64_t)p_aux[3] << 32)
         | ((uint64_t)p_aux[4] << 24)
         | ((uint64_t)p_aux[5] << 16)
         | ((uint64_t)p_aux[6] << 8)
         | ((uint64_t)p_aux[7] << 0);
}

static inline void ToSTC( uint8_t *p_aux, uint64_t i_stc )
{
    p_aux[0] = i_stc >> 56;
    p_aux[1] = (i_stc >> 48) & 0xff;
    p_aux[2] = (i_stc >> 40) & 0xff;
    p_aux[3] = (i_stc >> 32) & 0xff;
    p_aux[4] = (i_stc >> 24) & 0xff;
    p_aux[5] = (i_stc >> 16) & 0xff;
    p_aux[6] = (i_stc >> 8) & 0xff;
    p_aux[7] = (i_stc >> 0) & 0xff;
}
140 141

/*****************************************************************************
142
 * Retx helpers - biTStream style
143
 *****************************************************************************/
144
#define RETX_HEADER_SIZE 8
145

146
static inline void retx_init(uint8_t *p_retx)
147
{
148 149 150 151
    p_retx[0] = 'R';
    p_retx[1] = 'E';
    p_retx[2] = 'T';
    p_retx[3] = 'X';
152 153
}

154
static inline bool retx_check(const uint8_t *p_retx)
155
{
156 157
    return p_retx[0] == 'R' && p_retx[1] == 'E' && p_retx[2] == 'T' &&
           p_retx[3] == 'X';
158 159
}

160
static inline void retx_set_seqnum(uint8_t *p_retx, uint16_t i_seqnum)
161
{
162 163
    p_retx[4] = i_seqnum >> 8;
    p_retx[5] = i_seqnum & 0xff;
164 165
}

166
static inline uint16_t retx_get_seqnum(const uint8_t *p_retx)
167
{
168
    return ((uint16_t)p_retx[4] << 8) | p_retx[5];
169 170
}

171
static inline void retx_set_num(uint8_t *p_retx, uint16_t i_num)
172
{
173 174
    p_retx[6] = i_num >> 8;
    p_retx[7] = i_num & 0xff;
175 176
}

177
static inline uint16_t retx_get_num(const uint8_t *p_retx)
178
{
179
    return ((uint16_t)p_retx[6] << 8) | p_retx[7];
180
}