1 /*
2 * SRT - Secure, Reliable, Transport
3 * Copyright (c) 2018 Haivision Systems Inc.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 */
10
11 #include "socketoptions.hpp"
12 #include "verbose.hpp"
13
14 using namespace std;
15
16
17 extern const set<string> true_names = { "1", "yes", "on", "true" };
18 extern const set<string> false_names = { "0", "no", "off", "false" };
19
20 extern const std::map<std::string, int> enummap_transtype = {
21 { "live", SRTT_LIVE },
22 { "file", SRTT_FILE }
23 };
24
25
26 const char* const SocketOption::mode_names[3] = {
27 "listener", "caller", "rendezvous"
28 };
29
SrtInterpretMode(const string & modestr,const string & host,const string & adapter)30 SocketOption::Mode SrtInterpretMode(const string& modestr, const string& host, const string& adapter)
31 {
32 SocketOption::Mode mode = SocketOption::FAILURE;
33
34 if (modestr == "client" || modestr == "caller")
35 {
36 mode = SocketOption::CALLER;
37 }
38 else if (modestr == "server" || modestr == "listener")
39 {
40 mode = SocketOption::LISTENER;
41 }
42 else if (modestr == "rendezvous")
43 {
44 mode = SocketOption::RENDEZVOUS;
45 }
46 else if (modestr == "default")
47 {
48 // Use the following convention:
49 // 1. Server for source, Client for target
50 // 2. If host is empty, then always server.
51 if ( host == "" )
52 mode = SocketOption::LISTENER;
53 //else if ( !dir_output )
54 //mode = "server";
55 else
56 {
57 // Host is given, so check also "adapter"
58 if (adapter != "")
59 mode = SocketOption::RENDEZVOUS;
60 else
61 mode = SocketOption::CALLER;
62 }
63 }
64 else
65 {
66 mode = SocketOption::FAILURE;
67 }
68
69 return mode;
70 }
71
SrtConfigurePre(SRTSOCKET socket,string host,map<string,string> options,vector<string> * failures)72 SocketOption::Mode SrtConfigurePre(SRTSOCKET socket, string host, map<string, string> options, vector<string>* failures)
73 {
74 vector<string> dummy;
75 vector<string>& fails = failures ? *failures : dummy;
76
77 string modestr = "default", adapter;
78
79 if (options.count("mode"))
80 {
81 modestr = options["mode"];
82 }
83
84 if (options.count("adapter"))
85 {
86 adapter = options["adapter"];
87 }
88
89 SocketOption::Mode mode = SrtInterpretMode(modestr, host, adapter);
90 if (mode == SocketOption::FAILURE)
91 {
92 fails.push_back("mode");
93 }
94
95 if (options.count("linger"))
96 {
97 linger lin;
98 lin.l_linger = stoi(options["linger"]);
99 lin.l_onoff = lin.l_linger > 0 ? 1 : 0;
100 srt_setsockopt(socket, SocketOption::PRE, SRTO_LINGER, &lin, sizeof(linger));
101 }
102
103
104 bool all_clear = true;
105 for (const auto &o: srt_options)
106 {
107 if ( o.binding == SocketOption::PRE && options.count(o.name) )
108 {
109 string value = options.at(o.name);
110 bool ok = o.apply<SocketOption::SRT>(socket, value);
111 if ( !ok )
112 {
113 fails.push_back(o.name);
114 all_clear = false;
115 }
116 }
117 }
118
119 return all_clear ? mode : SocketOption::FAILURE;
120 }
121
SrtConfigurePost(SRTSOCKET socket,map<string,string> options,vector<string> * failures)122 void SrtConfigurePost(SRTSOCKET socket, map<string, string> options, vector<string>* failures)
123 {
124 vector<string> dummy;
125 vector<string>& fails = failures ? *failures : dummy;
126
127 for (const auto &o: srt_options)
128 {
129 if ( o.binding == SocketOption::POST && options.count(o.name) )
130 {
131 string value = options.at(o.name);
132 Verb() << "Setting option: " << o.name << " = " << value;
133 bool ok = o.apply<SocketOption::SRT>(socket, value);
134 if ( !ok )
135 fails.push_back(o.name);
136 }
137 }
138 }
139
140