Skip to content

Commit

Permalink
[core] Fixed incorrect setting streamid in internal config in HS (las…
Browse files Browse the repository at this point in the history
…t 4 characters) (#1868)

* Fixed also the length check condition in StringStorage
* Fixed problem with private option derivation (CONCEPT). Added UT to test derivation case
* Updated docs regarding the StreamID no applicable to the listener socket.
* Added UT for StreamID


Co-authored-by: maxsharabayko<maxsharabayko@haivision.com>
Co-authored-by: stevomatthews <smatthews@haivision.com>
  • Loading branch information
ethouris and stevomatthews authored Mar 17, 2021
1 parent 3605f6f commit 2bcc219
Show file tree
Hide file tree
Showing 4 changed files with 295 additions and 85 deletions.
4 changes: 4 additions & 0 deletions docs/APISocketOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,10 @@ override the value from the other side resulting in an arbitrary winner. Also
in this connection both peers are known to one another and both have equivalent
roles in the connection.

- **IMPORTANT**: This option is not derived by the accepted socket from the listener
socket, and setting it on a listener socket (see `srt_listen` function) doesn't
influence anything.

[Return to list](#list-of-options)

---
Expand Down
204 changes: 120 additions & 84 deletions srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,105 @@ const int UDT::ERROR = CUDT::ERROR;
2[15..0]: TsbPD delay [0..60000] msec
*/

extern const SRT_SOCKOPT srt_post_opt_list [SRT_SOCKOPT_NPOST] = {
SRTO_SNDSYN,
SRTO_RCVSYN,
SRTO_LINGER,
SRTO_SNDTIMEO,
SRTO_RCVTIMEO,
SRTO_MAXBW,
SRTO_INPUTBW,
SRTO_MININPUTBW,
SRTO_OHEADBW,
SRTO_SNDDROPDELAY,
SRTO_CONNTIMEO,
SRTO_DRIFTTRACER,
SRTO_LOSSMAXTTL
};

static const int32_t
SRTO_R_PREBIND = BIT(0), //< cannot be modified after srt_bind()
SRTO_R_PRE = BIT(1), //< cannot be modified after connection is established
SRTO_POST_SPEC = BIT(2); //< executes some action after setting the option

struct SrtOptionAction
{
int flags[SRTO_E_SIZE];
std::map<SRT_SOCKOPT, std::string> private_default;
SrtOptionAction()
{
// Set everything to 0 to clear all flags
// When an option isn't present here, it means that:
// * it is not settable, or
// * the option is POST (non-restricted)
// * it has no post-actions
// The post-action may be defined independently on restrictions.
memset(flags, 0, sizeof flags);

flags[SRTO_MSS] = SRTO_R_PREBIND;
flags[SRTO_FC] = SRTO_R_PRE;
flags[SRTO_SNDBUF] = SRTO_R_PREBIND;
flags[SRTO_RCVBUF] = SRTO_R_PREBIND;
flags[SRTO_UDP_SNDBUF] = SRTO_R_PREBIND;
flags[SRTO_UDP_RCVBUF] = SRTO_R_PREBIND;
flags[SRTO_RENDEZVOUS] = SRTO_R_PRE;
flags[SRTO_REUSEADDR] = SRTO_R_PREBIND;
flags[SRTO_MAXBW] = SRTO_POST_SPEC;
flags[SRTO_SENDER] = SRTO_R_PRE;
flags[SRTO_TSBPDMODE] = SRTO_R_PRE;
flags[SRTO_LATENCY] = SRTO_R_PRE;
flags[SRTO_INPUTBW] = 0 | SRTO_POST_SPEC;
flags[SRTO_MININPUTBW] = 0 | SRTO_POST_SPEC;
flags[SRTO_OHEADBW] = 0 | SRTO_POST_SPEC;
flags[SRTO_PASSPHRASE] = SRTO_R_PRE;
flags[SRTO_PBKEYLEN] = SRTO_R_PRE;
flags[SRTO_IPTTL] = SRTO_R_PREBIND;
flags[SRTO_IPTOS] = SRTO_R_PREBIND;
flags[SRTO_TLPKTDROP] = SRTO_R_PRE;
flags[SRTO_SNDDROPDELAY] = SRTO_R_PRE;
flags[SRTO_NAKREPORT] = SRTO_R_PRE;
flags[SRTO_VERSION] = SRTO_R_PRE;
flags[SRTO_LOSSMAXTTL] = 0 | SRTO_POST_SPEC;
flags[SRTO_RCVLATENCY] = SRTO_R_PRE;
flags[SRTO_PEERLATENCY] = SRTO_R_PRE;
flags[SRTO_MINVERSION] = SRTO_R_PRE;
flags[SRTO_STREAMID] = SRTO_R_PRE;
flags[SRTO_CONGESTION] = SRTO_R_PRE;
flags[SRTO_MESSAGEAPI] = SRTO_R_PRE;
flags[SRTO_PAYLOADSIZE] = SRTO_R_PRE;
flags[SRTO_TRANSTYPE] = SRTO_R_PREBIND;
flags[SRTO_KMREFRESHRATE] = SRTO_R_PRE;
flags[SRTO_KMPREANNOUNCE] = SRTO_R_PRE;
flags[SRTO_ENFORCEDENCRYPTION] = SRTO_R_PRE;
flags[SRTO_IPV6ONLY] = SRTO_R_PREBIND;
flags[SRTO_PEERIDLETIMEO] = SRTO_R_PRE;
#ifdef SRT_ENABLE_BINDTODEVICE
flags[SRTO_BINDTODEVICE] = SRTO_R_PREBIND;
#endif
#if ENABLE_EXPERIMENTAL_BONDING
flags[SRTO_GROUPCONNECT] = SRTO_R_PRE;
#endif
flags[SRTO_PACKETFILTER] = SRTO_R_PRE;
flags[SRTO_RETRANSMITALGO] = SRTO_R_PRE;

// For "private" options (not derived from the listener
// socket by an accepted socket) provide below private_default
// to which these options will be reset after blindly
// copying the option object from the listener socket.
// Note that this option cannot have runtime-dependent
// default value, like options affected by SRTO_TRANSTYPE.

// Options may be of different types, but this value should be only
// used as a source of the value. For example, in case of int64_t you'd
// have to place here a string of 8 characters. It should be copied
// always in the hardware order, as this is what will be directly
// passed to a setting function.
private_default[SRTO_STREAMID] = string();
}
}
srt_options_action;


void CUDT::construct()
{
m_pSndBuffer = NULL;
Expand Down Expand Up @@ -192,6 +291,26 @@ CUDT::CUDT(CUDTSocket* parent, const CUDT& ancestor): m_parent(parent)
// into a separate class for easier copying.

m_config = ancestor.m_config;
// Reset values that shall not be derived to default ones.
// These declarations should be consistent with SRTO_R_PRIVATE flag.
for (size_t i = 0; i < Size(srt_options_action.flags); ++i)
{
string* pdef = map_getp(srt_options_action.private_default, SRT_SOCKOPT(i));
if (pdef)
{
try
{
// Ignore errors here - this is a development-time granted
// value, not user-provided value.
m_config.set(SRT_SOCKOPT(i), pdef->data(), pdef->size());
}
catch (...)
{
LOGC(gglog.Error, log << "IPE: failed to set a declared default option!");
}
}
}

m_SrtHsSide = ancestor.m_SrtHsSide; // actually it sets it to HSD_RESPONDER
m_bTLPktDrop = ancestor.m_bTLPktDrop;
m_iReorderTolerance = m_config.iMaxReorderTolerance; // Initialize with maximum value
Expand All @@ -214,89 +333,6 @@ CUDT::~CUDT()
delete m_pRNode;
}

extern const SRT_SOCKOPT srt_post_opt_list [SRT_SOCKOPT_NPOST] = {
SRTO_SNDSYN,
SRTO_RCVSYN,
SRTO_LINGER,
SRTO_SNDTIMEO,
SRTO_RCVTIMEO,
SRTO_MAXBW,
SRTO_INPUTBW,
SRTO_MININPUTBW,
SRTO_OHEADBW,
SRTO_SNDDROPDELAY,
SRTO_CONNTIMEO,
SRTO_DRIFTTRACER,
SRTO_LOSSMAXTTL
};

static const int32_t
SRTO_R_PREBIND = BIT(0),
SRTO_R_PRE = BIT(1),
SRTO_POST_SPEC = BIT(2);

struct SrtOptionAction
{
int flags[SRTO_E_SIZE];
SrtOptionAction()
{
// Set everything to 0 to clear all flags
// When an option isn't present here, it means that:
// * it is not settable, or
// * the option is POST (non-restricted)
// * it has no post-actions
// The post-action may be defined independently on restrictions.
memset(flags, 0, sizeof flags);

flags[SRTO_MSS] = SRTO_R_PREBIND;
flags[SRTO_FC] = SRTO_R_PRE;
flags[SRTO_SNDBUF] = SRTO_R_PREBIND;
flags[SRTO_RCVBUF] = SRTO_R_PREBIND;
flags[SRTO_UDP_SNDBUF] = SRTO_R_PREBIND;
flags[SRTO_UDP_RCVBUF] = SRTO_R_PREBIND;
flags[SRTO_RENDEZVOUS] = SRTO_R_PRE;
flags[SRTO_REUSEADDR] = SRTO_R_PREBIND;
flags[SRTO_MAXBW] = SRTO_POST_SPEC;
flags[SRTO_SENDER] = SRTO_R_PRE;
flags[SRTO_TSBPDMODE] = SRTO_R_PRE;
flags[SRTO_LATENCY] = SRTO_R_PRE;
flags[SRTO_INPUTBW] = 0 | SRTO_POST_SPEC;
flags[SRTO_MININPUTBW] = 0 | SRTO_POST_SPEC;
flags[SRTO_OHEADBW] = 0 | SRTO_POST_SPEC;
flags[SRTO_PASSPHRASE] = SRTO_R_PRE;
flags[SRTO_PBKEYLEN] = SRTO_R_PRE;
flags[SRTO_IPTTL] = SRTO_R_PREBIND;
flags[SRTO_IPTOS] = SRTO_R_PREBIND;
flags[SRTO_TLPKTDROP] = SRTO_R_PRE;
flags[SRTO_SNDDROPDELAY] = SRTO_R_PRE;
flags[SRTO_NAKREPORT] = SRTO_R_PRE;
flags[SRTO_VERSION] = SRTO_R_PRE;
flags[SRTO_LOSSMAXTTL] = 0 | SRTO_POST_SPEC;
flags[SRTO_RCVLATENCY] = SRTO_R_PRE;
flags[SRTO_PEERLATENCY] = SRTO_R_PRE;
flags[SRTO_MINVERSION] = SRTO_R_PRE;
flags[SRTO_STREAMID] = SRTO_R_PRE;
flags[SRTO_CONGESTION] = SRTO_R_PRE;
flags[SRTO_MESSAGEAPI] = SRTO_R_PRE;
flags[SRTO_PAYLOADSIZE] = SRTO_R_PRE;
flags[SRTO_TRANSTYPE] = SRTO_R_PREBIND;
flags[SRTO_KMREFRESHRATE] = SRTO_R_PRE;
flags[SRTO_KMPREANNOUNCE] = SRTO_R_PRE;
flags[SRTO_ENFORCEDENCRYPTION] = SRTO_R_PRE;
flags[SRTO_IPV6ONLY] = SRTO_R_PREBIND;
flags[SRTO_PEERIDLETIMEO] = SRTO_R_PRE;
#ifdef SRT_ENABLE_BINDTODEVICE
flags[SRTO_BINDTODEVICE] = SRTO_R_PREBIND;
#endif
#if ENABLE_EXPERIMENTAL_BONDING
flags[SRTO_GROUPCONNECT] = SRTO_R_PRE;
#endif
flags[SRTO_PACKETFILTER] = SRTO_R_PRE;
flags[SRTO_RETRANSMITALGO] = SRTO_R_PRE;
}
}
srt_options_action;

void CUDT::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen)
{
if (m_bBroken || m_bClosing)
Expand Down Expand Up @@ -2570,7 +2606,7 @@ bool CUDT::interpretSrtHandshake(const CHandShake& hs,
// Un-swap on big endian machines
ItoHLA((uint32_t *)target, (uint32_t *)target, blocklen);

m_config.sStreamName.set(target, bytelen);
m_config.sStreamName.set(target, strlen(target));
HLOGC(cnlog.Debug,
log << "CONNECTOR'S REQUESTED SID [" << m_config.sStreamName.c_str() << "] (bytelen=" << bytelen
<< " blocklen=" << blocklen << ")");
Expand Down
2 changes: 1 addition & 1 deletion srtcore/socketconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class StringStorage

bool set(const char* s, size_t length)
{
if (length >= SIZE)
if (length > SIZE)
return false;

memcpy(stor, s, length);
Expand Down
Loading

0 comments on commit 2bcc219

Please sign in to comment.