This patch supports the new SRT streamid spec allowing caller to send
key/value pairs
of parameters to the listener, including user name. A callback parses the
streamid
- in this case, the parsers chooses the passphrase for the user based on
specified list
of passphrases.
Thanks,
Aaron
From a28ef3c7d7d02b273786a659f9e1d468fd29d0a5 Mon Sep 17 00:00:00 2001
From: Aaron Boxer
Date: Wed, 14 Aug 2019 08:26:17 -0400
Subject: [PATCH] libsrt: support streamid spec
---
libavformat/libsrt.c | 131 +++
1 file changed, 131 insertions(+)
diff --git a/libavformat/libsrt.c b/libavformat/libsrt.c
index b5568089fa..02fd840b37 100644
--- a/libavformat/libsrt.c
+++ b/libavformat/libsrt.c
@@ -34,6 +34,9 @@
#include "os_support.h"
#include "url.h"
+
+static srt_listen_callback_fn libsrt_listen_callback;
+
/* This is for MPEG-TS and it's a default SRTO_PAYLOADSIZE for SRTT_LIVE (8 TS packets) */
#ifndef SRT_LIVE_DEFAULT_PAYLOAD_SIZE
#define SRT_LIVE_DEFAULT_PAYLOAD_SIZE 1316
@@ -62,6 +65,7 @@ typedef struct SRTContext {
int64_t maxbw;
int pbkeylen;
char *passphrase;
+char* user_passphrase_list;
int mss;
int ffs;
int ipttl;
@@ -101,6 +105,7 @@ static const AVOption libsrt_options[] = {
{ "maxbw", "Maximum bandwidth (bytes per second) that the connection can use", OFFSET(maxbw),AV_OPT_TYPE_INT64,{ .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
{ "pbkeylen", "Crypto key len in bytes {16,24,32} Default: 16 (128-bit)", OFFSET(pbkeylen), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 32,.flags = D|E },
{ "passphrase", "Crypto PBKDF2 Passphrase size[0,10..64] 0:disable crypto", OFFSET(passphrase), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E },
+{ "user_passphrase_list", "Comma separated list users and passphrases, of form usrr1=pass1,usr2=pass2,...", OFFSET(user_passphrase_list), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E },
{ "mss","The Maximum Segment Size", OFFSET(mss), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1500, .flags = D|E },
{ "ffs","Flight flag size (window size) (in bytes)",OFFSET(ffs), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
{ "ipttl", "IP Time To Live", OFFSET(ipttl),AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
@@ -196,6 +201,128 @@ static int libsrt_network_wait_fd_timeout(URLContext *h, int eid, int fd, int wr
}
}
+typedef struct _libsrt_parsed_param {
+char *key;
+char *val;
+} libsrt_parsed_param;
+
+
+/**
+ * Parse a key-value string into an array of key/value structs.
+ *
+ * The key-value string should be a null terminated string of parameters separated
+ * by a delimiter. Each parameter are checked for the equal sign character.
+ * If the equal sign character appears in the parameter, it will be used as a null terminator
+ * and the part that comes after it will be the value of the parameter.
+ *
+ *
+ * param: keyvalue: the key-value string to parse. The string will be modified.
+ * param: delimiter:the character that separates the key/value pairs
+ * from each other.
+ * param: params: an array of parsed_param structs to hold the result.
+ * param: max_params: maximum number of parameters to parse.
+ *
+ * Return:the number of parsed items. -1 if there was an error.
+ */
+static int libsrt_parse_key_value(char *keyvalue, const char* delimiter,
+libsrt_parsed_param *params, int max_params)
+{
+int i = 0;
+char *token = NULL;
+
+if (!keyvalue || *keyvalue == '\0')
+return -1;
+if (!params || max_params == 0)
+return 0;
+
+token = strtok( keyvalue, delimiter );
+while (token != NULL && i < max_params) {
+params[i].key = token;
+params[i].val = NULL;
+if ((params[i].val = strchr( params[i].key, '=' )) != NULL) {
+size_t val_len = strlen( params[i].val );
+/* make key into a zero-delimited string */
+*(params[i].val) = '\0';
+/* make sure val is not empty */
+if (val_len > 1) {
+params[i].val++;
+/* make sure key is not empty */
+if (params[i].key[0])
+i++;
+};
+}
+token = strtok( NULL, delimiter );
+}
+
+return i;
+}
+
+/* callback to parse streamid */
+static int libsrt_listen_callback(void* opaq, SRTSOCKET ns, int hsversion, const struct sockaddr* peeraddr, const char* streamid)
+{
+const char* username = NULL;
+const char* expected_passphrase = NULL;
+static const char stdhdr [] = "#!::";
+uint32_t*