-
Notifications
You must be signed in to change notification settings - Fork 840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The integrated handshake feature (aka HSv5) with some refactoring #76
Conversation
@@ -166,7 +166,12 @@ SocketOption srt_options [] { | |||
{ "tsbpddelay", 0, SRTO_TSBPDDELAY, SocketOption::INT, SocketOption::PRE }, | |||
{ "tlpktdrop", 0, SRTO_TLPKTDROP, SocketOption::BOOL, SocketOption::PRE }, | |||
{ "nakreport", 0, SRTO_NAKREPORT, SocketOption::BOOL, SocketOption::PRE }, | |||
{ "conntimeo", 0, SRTO_CONNTIMEO, SocketOption::INT, SocketOption::PRE } | |||
{ "conntimeo", 0, SRTO_CONNTIMEO, SocketOption::INT, SocketOption::PRE }, | |||
{ "lossmaxttl", 0, SRTO_LOSSMAXTTL, SocketOption::INT, SocketOption::PRE }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw no desctiption of this in the pull request comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a minor change, this option was there since a long time (at least since the github version) and I forgot to expose it through socketoptions.
int err = NET_ERROR; | ||
if ( err != EAGAIN ) // For EAGAIN, this isn't an error, just a useless call. | ||
if ( err == EAGAIN || err == EINTR ) // For EAGAIN, this isn't an error, just a useless call. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come is EINTR a retry later. Most probably an application terminating I may have found why my CLI test app do not terminate as before on Ctrl-C.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EINTR is "interrupted system call". It can also happen when an application gets SIGUSR1 sent from some other process because the application was designed to work with this. This signal is theoretically unrelated to SRT, but still it's a signal and it will interrupt a system call, like every signal does. This is generally a problem for libraries, and a library must be as transparent as possible for signals. Not sure if EINTR is even possible in nonblocking mode, but at least I can imagine such a situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EINTR is fatal for most normal applications and library should have means of indicating this condition to the main application code. Please do not treat it as "try again".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not discuss such details here. This is a long story, I don't want to spread large comments here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @ethouris , I don't think Jean and me are looking for a story but rather for explanation why we should be masking EINTR in this particular case. Also I believe Jean thinks this is already breaking his app so if this change is to blame for CTRL-C not working it is a bug.
7fb22d7
to
9c90ca5
Compare
Have no idea what happened to this threadname.h in srtcore directory. It must remain there until this branch is merged into upstream, I'll delete it somehow later. |
NOTE: this should be merged NOT to a master branch, but to a feature branch, with a name proposed as the source branch: dev-integrated-handshake.
This is the "integrated handshake" feature, aka HSv5, which makes the SRT portion of the handshake, including encryption, done in the same process as the UDT handshake.
The old way for exchanging the SRT specific information was the following:
SRTO_SENDER
option starts sending messages based onUMSG_EXT
withSRT_CMD_HSREQ
, just before sending any data at the first call toUDT::sendmsg
. Then it awaits a response withSRT_CMD_HSRSP
the same way.UMSG_EXT
messages withSRT_CMD_KMREQ
, and so it awaitsSRT_CMD_KMRSP
.The problem with the old way was that the whole process completes after several messages with data have been sent already, and if the data were encrypted, the receiver was unable to decrypt them until the KMREQ message arrives. Also due to an "important" bug in the UDT code it took quite a time to establish the connection (sometimes 1-3 seconds).
In HSv5 the HSREQ/HSRSP and KMREQ/KMRSP are attached to the handshake messages of type "conclusion" (in caller-listener it's the second part, after "induction" did the cookie exchange, in rendezvous it's either the very first message or the response to the initial "waveahand" message). Because of that the new term was introduced, which is "handshake side": INITIATOR and RESPONDER, which is also used for HSv4. INITIATOR should send HSREQ/KMREQ information to RESPONDER, which should respond with HSRSP/KMRSP.
For HSv4 it's simple - INITIATOR is the party that is set
SRTO_SENDER
, the other one is RESPONDER. This is regardless of the connection method and side.For HSv5:
Note that in result in HSv5 has more chances to fail during the connection, however once the connection is established with the handshake process, it's completely configured for latency and encryption since the first sent byte, and handshake process - at least for the blocking mode - takes a fraction of a second (I didn't measure it exactly, but I predict it should be not more than 4*RTT).
Note also that since HSv5 SRT is bidirectional by default (there's even no "direction" term at all), so
SRTO_TWOWAYDATA
has been removed andSRTO_SENDER
option is not necessary if you don't plan to communicate with the old client.Secondary changes done here include:
SRTO_TWOWAYDATA
option. The only bidirectional support is with HSv5, the new handshake and it's bidirectional by default.SRTO_RCVLATENCY
andSRTO_PEERLATENCY
. The old optionSRTO_LATENCY
sets both these latter options to the same value. Note that for one direction this will effectively work the same way as before (because the sender will effectively ignoreSRTO_RCVLATENCY
setting as well asSRTO_PEERLATENCY
received from the peer receiver, as the sender isn't receiving).SRT_ENABLE_TSBPD
,SRT_ENABLE_BSTATS
andHAI_PATCH
and the alternative code. I hope you'll feel more convenient with this.SRTO_MINVERSION
. The value's syntax is for 32-bit integer0x00JJNNPP
, where JJ NN and PP mean Major, Minor and Patch, so 1.2.3 version will be0x00010203
. This is the minimum version required for the peer, meaning that when the peer's SRT version is less than this value, the connection will be rejected. This is useful if you, for example, require a bidirectional connection for your application to work correctly. Note though that this feature works only since a version that supports HSv5, so any HSv4 peer will fail to satisfy ANY minimum version requirement - leave this value with 0 to prevent any minimum version check. There's also a symbol introducedSRT_VERSION_FEAT_HSv5
set to 1.3.0 (this) version - you can use that value to request that the peer support HSv5 or check if it does (bySRTO_PEERVERSION
).SRTO_STREAMID
, plus two functions to get/set the ID, as the C interface for these options is a little bit clumsy. This sets the text-based identifier (maximum 512 bytes) to a socket that will be then connecting. When the listener side accepts the connection, the same identifier will be set to a socket returned byaccept()
and can be retrieved using this option. You can treat this as a kinda "port number extension" so that the application may serve multiple various streams using one port, where the stream can be selected by identifier. There's also a new application calledsiplex
that demonstrates this feature, together with another existing feature since always - a possibility to use one outgoing port (and therefore one UDP socket) for multiple SRT sockets.