1 /* -*- c-basic-offset: 8; -*- */ 2 /* shout.h: Private libshout data structures and declarations 3 * 4 * Copyright (C) 2002-2004 the Icecast team <team@icecast.org>, 5 * Copyright (C) 2012-2019 Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 * 17 * You should have received a copy of the GNU Library General Public 18 * License along with this library; if not, write to the Free 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 21 * $Id$ 22 */ 23 24 #ifndef __LIBSHOUT_SHOUT_PRIVATE_H__ 25 #define __LIBSHOUT_SHOUT_PRIVATE_H__ 26 27 #ifdef HAVE_CONFIG_H 28 # include "config.h" 29 #endif 30 31 #include <shout/shout.h> 32 #include <common/net/sock.h> 33 #include <common/timing/timing.h> 34 #include "util.h" 35 36 #include <sys/types.h> 37 38 #ifdef HAVE_STDINT_H 39 # include <stdint.h> 40 #elif defined (HAVE_INTTYPES_H) 41 # include <inttypes.h> 42 #endif 43 44 #ifdef HAVE_OPENSSL 45 # include <openssl/ssl.h> 46 #endif 47 48 #define LIBSHOUT_DEFAULT_HOST "localhost" 49 #define LIBSHOUT_DEFAULT_PORT 8000 50 #define LIBSHOUT_DEFAULT_FORMAT SHOUT_FORMAT_OGG 51 #define LIBSHOUT_DEFAULT_USAGE SHOUT_USAGE_UNKNOWN 52 #define LIBSHOUT_DEFAULT_PROTOCOL SHOUT_PROTOCOL_HTTP 53 #define LIBSHOUT_DEFAULT_USER "source" 54 #define LIBSHOUT_DEFAULT_USERAGENT "libshout/" VERSION 55 #define LIBSHOUT_DEFAULT_ALLOWED_CIPHERS "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" /* Mozilla's 'Intermediate' list as of 2015-04-19 */ 56 57 /* server capabilities. 58 0x000000XXUL -> Methods. 59 0x0000XX00UL -> HTTP Options 60 0x000X0000UL -> TLS Related 61 0xX0000000UL -> State related 62 0x0XX00000UL -> Reserved 63 */ 64 #define LIBSHOUT_CAP_SOURCE 0x00000001UL 65 #define LIBSHOUT_CAP_PUT 0x00000002UL 66 #define LIBSHOUT_CAP_GET 0x00000004UL 67 #define LIBSHOUT_CAP_POST 0x00000008UL 68 #define LIBSHOUT_CAP_OPTIONS 0x00000010UL 69 #define LIBSHOUT_CAP_CHUNKED 0x00000100UL 70 #define LIBSHOUT_CAP_100CONTINUE 0x00000200UL 71 #define LIBSHOUT_CAP_UPGRADETLS 0x00010000UL 72 #define LIBSHOUT_CAP_REQAUTH 0x20000000UL /* requires authentication */ 73 #define LIBSHOUT_CAP_CHALLENGED 0x40000000UL 74 #define LIBSHOUT_CAP_GOTCAPS 0x80000000UL 75 76 #define LIBSHOUT_MAX_RETRY 3 77 78 #define SHOUT_BUFSIZE 4096 79 80 typedef struct _shout_tls shout_tls_t; 81 82 typedef struct _shout_buf { 83 unsigned char data[SHOUT_BUFSIZE]; 84 unsigned int len; 85 unsigned int pos; 86 87 struct _shout_buf *prev; 88 struct _shout_buf *next; 89 } shout_buf_t; 90 91 typedef struct { 92 shout_buf_t *head; 93 size_t len; 94 } shout_queue_t; 95 96 typedef enum { 97 SHOUT_SOCKSTATE_UNCONNECTED = 0, 98 SHOUT_SOCKSTATE_CONNECTING, 99 SHOUT_SOCKSTATE_CONNECTED, 100 SHOUT_SOCKSTATE_TLS_CONNECTING, 101 SHOUT_SOCKSTATE_TLS_CONNECTED, 102 SHOUT_SOCKSTATE_TLS_VERIFIED 103 } shout_connect_socket_state_t; 104 105 typedef enum { 106 SHOUT_MSGSTATE_IDLE = 0, 107 SHOUT_MSGSTATE_CREATING0, 108 SHOUT_MSGSTATE_SENDING0, 109 SHOUT_MSGSTATE_WAITING0, 110 SHOUT_MSGSTATE_RECEIVING0, 111 SHOUT_MSGSTATE_RECEIVED0, 112 SHOUT_MSGSTATE_PARSED_INFORMATIONAL0, 113 SHOUT_MSGSTATE_CREATING1, 114 SHOUT_MSGSTATE_SENDING1, 115 SHOUT_MSGSTATE_WAITING1, 116 SHOUT_MSGSTATE_RECEIVING1, 117 SHOUT_MSGSTATE_RECEIVED1, 118 SHOUT_MSGSTATE_PARSED_INFORMATIONAL1, 119 SHOUT_MSGSTATE_PARSED_FINAL 120 } shout_connect_message_state_t; 121 122 typedef enum { 123 SHOUT_RS_DONE, 124 SHOUT_RS_TIMEOUT, 125 SHOUT_RS_NOTNOW, 126 SHOUT_RS_ERROR 127 } shout_connection_return_state_t; 128 129 typedef union shout_protocol_extra_tag { 130 int si; 131 void *vp; 132 } shout_protocol_extra_t; 133 134 typedef struct { 135 int is_source; 136 int fake_ua; 137 int auth; 138 const char *method; 139 const char *resource; 140 const char *param; 141 } shout_http_plan_t; 142 143 typedef struct shout_connection_tag shout_connection_t; 144 145 typedef struct { 146 shout_connection_return_state_t (*msg_create)(shout_t *self, shout_connection_t *connection); 147 shout_connection_return_state_t (*msg_get)(shout_t *self, shout_connection_t *connection); 148 shout_connection_return_state_t (*msg_parse)(shout_t *self, shout_connection_t *connection); 149 shout_connection_return_state_t (*protocol_iter)(shout_t *self, shout_connection_t *connection); 150 } shout_protocol_impl_t; 151 152 typedef int (*shout_connection_callback_t)(shout_connection_t *con, shout_event_t event, void *userdata, va_list ap); 153 154 struct shout_connection_tag { 155 size_t refc; 156 157 int selected_tls_mode; 158 shout_connect_socket_state_t target_socket_state; 159 shout_connect_socket_state_t current_socket_state; 160 shout_connect_message_state_t target_message_state; 161 shout_connect_message_state_t current_message_state; 162 int target_protocol_state; 163 int current_protocol_state; 164 shout_protocol_extra_t protocol_extra; 165 166 const shout_protocol_impl_t *impl; 167 const void *plan; 168 169 int (*any_timeout)(shout_t *self, shout_connection_t *connection); 170 int (*destory)(shout_connection_t *connection); 171 172 int nonblocking; 173 174 shout_connection_callback_t callback; 175 void *callback_userdata; 176 177 #ifdef HAVE_OPENSSL 178 shout_tls_t *tls; 179 #endif 180 sock_t socket; 181 shout_queue_t rqueue; 182 shout_queue_t wqueue; 183 184 uint64_t wait_timeout; 185 /* maybe we want to convert this to general flag vector later */ 186 int wait_timeout_happened; 187 188 /* server capabilities (LIBSHOUT_CAP_*) */ 189 uint32_t server_caps; 190 191 int error; 192 }; 193 194 struct shout { 195 /* hostname or IP of icecast server */ 196 char *host; 197 /* port of the icecast server */ 198 int port; 199 /* login password for the server */ 200 char *password; 201 /* server protocol to use */ 202 unsigned int protocol; 203 /* type of data being sent */ 204 unsigned int format; 205 unsigned int usage; 206 /* audio encoding parameters */ 207 util_dict *audio_info; 208 /* content-language */ 209 char *content_language; 210 211 /* user-agent to use when doing HTTP login */ 212 char *useragent; 213 /* mountpoint for this stream */ 214 char *mount; 215 /* all the meta data about the stream */ 216 util_dict *meta; 217 /* icecast 1.x dumpfile */ 218 char *dumpfile; 219 /* username to use for HTTP auth. */ 220 char *user; 221 /* is this stream private? */ 222 int public; 223 224 shout_callback_t callback; 225 void *callback_userdata; 226 227 /* TLS options */ 228 #ifdef HAVE_OPENSSL 229 int tls_mode; 230 char *ca_directory; 231 char *ca_file; 232 char *allowed_ciphers; 233 char *client_certificate; 234 #endif 235 236 union { 237 shout_http_plan_t http; 238 } source_plan; 239 240 /* socket the connection is on */ 241 shout_connection_t *connection; 242 int nonblocking; 243 244 void *format_data; 245 int (*send)(shout_t* self, const unsigned char* buff, size_t len); 246 void (*close)(shout_t* self); 247 248 /* start of this period's timeclock */ 249 uint64_t starttime; 250 /* amount of data we've sent (in microseconds) */ 251 uint64_t senttime; 252 253 int error; 254 }; 255 256 /* helper functions */ 257 const char *shout_get_mimetype_from_self(shout_t *self); 258 259 int shout_queue_data(shout_queue_t *queue, const unsigned char *data, size_t len); 260 int shout_queue_str(shout_connection_t *self, const char *str); 261 int shout_queue_printf(shout_connection_t *self, const char *fmt, ...); 262 void shout_queue_free(shout_queue_t *queue); 263 ssize_t shout_queue_collect(shout_buf_t *queue, char **buf); 264 265 /* transports */ 266 ssize_t shout_conn_read(shout_t *self, void *buf, size_t len); 267 ssize_t shout_conn_write(shout_t *self, const void *buf, size_t len); 268 int shout_conn_recoverable(shout_t *self); 269 270 /* connection */ 271 ssize_t shout_connection__read(shout_connection_t *con, shout_t *shout, void *buf, size_t len); 272 int shout_connection__recoverable(shout_connection_t *con, shout_t *shout); 273 shout_connection_t *shout_connection_new(shout_t *self, const shout_protocol_impl_t *impl, const void *plan); 274 int shout_connection_ref(shout_connection_t *con); 275 int shout_connection_unref(shout_connection_t *con); 276 int shout_connection_iter(shout_connection_t *con, shout_t *shout); 277 int shout_connection_select_tlsmode(shout_connection_t *con, int tlsmode); 278 int shout_connection_set_nonblocking(shout_connection_t *con, unsigned int nonblocking); 279 int shout_connection_set_wait_timeout(shout_connection_t *con, shout_t *shout, uint64_t timeout /* [ms] */); 280 int shout_connection_get_wait_timeout_happened(shout_connection_t *con, shout_t *shout); /* returns SHOUTERR_* or > 0 for true */ 281 int shout_connection_connect(shout_connection_t *con, shout_t *shout); 282 int shout_connection_disconnect(shout_connection_t *con); 283 ssize_t shout_connection_send(shout_connection_t *con, shout_t *shout, const void *buf, size_t len); 284 ssize_t shout_connection_get_sendq(shout_connection_t *con, shout_t *shout); 285 int shout_connection_starttls(shout_connection_t *con, shout_t *shout); 286 int shout_connection_set_error(shout_connection_t *con, int error); 287 int shout_connection_get_error(shout_connection_t *con); 288 int shout_connection_transfer_error(shout_connection_t *con, shout_t *shout); 289 int shout_connection_control(shout_connection_t *con, shout_control_t control, ...); 290 int shout_connection_set_callback(shout_connection_t *con, shout_connection_callback_t callback, void *userdata); 291 292 #ifdef HAVE_OPENSSL 293 typedef int (*shout_tls_callback_t)(shout_tls_t *tls, shout_event_t event, void *userdata, va_list ap); 294 295 shout_tls_t *shout_tls_new(shout_t *self, sock_t socket); 296 int shout_tls_try_connect(shout_tls_t *tls); 297 int shout_tls_close(shout_tls_t *tls); 298 ssize_t shout_tls_read(shout_tls_t *tls, void *buf, size_t len); 299 ssize_t shout_tls_write(shout_tls_t *tls, const void *buf, size_t len); 300 int shout_tls_recoverable(shout_tls_t *tls); 301 int shout_tls_get_peer_certificate(shout_tls_t *tls, char **buf); 302 int shout_tls_get_peer_certificate_chain(shout_tls_t *tls, char **buf); 303 int shout_tls_set_callback(shout_tls_t *tls, shout_tls_callback_t callback, void *userdata); 304 #endif 305 306 /* protocols */ 307 extern const shout_protocol_impl_t *shout_http_impl; 308 extern const shout_protocol_impl_t *shout_xaudiocast_impl; 309 extern const shout_protocol_impl_t *shout_icy_impl; 310 extern const shout_protocol_impl_t *shout_roaraudio_impl; 311 312 shout_connection_return_state_t shout_get_xaudiocast_response(shout_t *self, shout_connection_t *connection); 313 shout_connection_return_state_t shout_parse_xaudiocast_response(shout_t *self, shout_connection_t *connection); 314 315 /* containers */ 316 int shout_open_ogg(shout_t *self); 317 int shout_open_mp3(shout_t *self); 318 int shout_open_webm(shout_t *self); 319 320 #endif /* __LIBSHOUT_SHOUT_PRIVATE_H__ */ 321