-
Notifications
You must be signed in to change notification settings - Fork 42
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
RTCSctpTransport lacks remote port #625
Comments
On second thought, adding |
Since getCapabilities is static, it can only return generic capabilities like maxMessageSize, and not things like the local port, which are specific to an RTCSctpTransport object. Which makes me wonder whether it shouldn't be getLocalParameters() instead. |
Oh, it's static. I haven't seen that. I'd upvote changing it to a non-static |
Something related I ran into recently: in WebRTC 1.0, the local/remote SCTP ports are technically allowed to change. Mapping this to ORTC: If the remote port changes, you can just call Unless we do want a new WebRTC |
Can you give a reference to a related RFC/draft that clarifies how this works for WebRTC? Does it use SCTP multihoming to add an address/port pair to the association? I haven't found anything in Google's code or in Mozilla's code regarding this (no calls to Furthermore, ORTC doesn't really specify what's supposed to happen when calling |
JSEP points to draft-ietf-mmusic-sctp-sdp which says:
So I think the whole association is just closed and recreated. Chrome doesn't quite do this properly, but it does happen if you change the "m=" section direction to "inactive" and then back. |
I hope you don't mind me asking but do you know of a use case for this procedure? To add support for this, we would have to move most of the description for the |
Another question I have is: What are the implications for open data channels? What if I choose to send a message at the very same moment where no SCTP association is available. Do you know if this is specified somewhere @taylor-b? I'm especially interested in the SCTP and data channel state relationship. (Sorry if this is a little bit off-topic) |
The data channel state wouldn't be "open" then, so you'd get an
I don't know a use case. Maybe the easiest solution is to just say "this isn't allowed" in JSEP. Or do what I mentioned earlier, and create a new SctpTransport for each association. I'll raise this question in the WebRTC working group: w3c/webrtc-pc#979 |
Some possibilities:
Approach 1 allows the start method to be called again to change the remote port. Approach 2 would require a new object if either the local or remote port changes. |
Option 1 opens up a new problem: The average user doesn't want to specify which local port is going to be used. Furthermore, no check can be made whether the local port is actually available before calling the constructor. But when the constructor is being called, the remote port must already be known. Effectively, two peers would have to announce their local port to each other before knowing whether that port can be used. I'm voting for 3 as it seems much more consistent to the rest of the API to have a parameters dict for SCTP as well. Furthermore, I'm suggesting to keep the local port argument at the constructor but add it to the In ORTC, If I understand correctly (and please correct me if I'm wrong @taylor-b), this is different to WebRTC where the data channels are only temporarily closed until the local port has been changed and a new data transport instance has been established. Then, they are reopened. So to maintain compatibility, we would have to be able to change both local and remote port without creating a new |
I'd vote for 3 too.
Actually, I think WebRTC is the same in this respect:
And there's no mention of it returning from "closing"/"closed".
Unless we say "there's one I don't think WebRTC specifies this behavior right now, unless I'm overlooking something. |
Thanks for your correction. Fair enough, in that case option 3 as suggested by @aboba should do. Considering that WebRTC doesn't specify this behaviour (yet), maybe we should keep it simple for now and describe that subsequent calls to |
On the topic of remote ports: in the SDP/JSEP world, the local (client) and remote (server) ports must be the same. See draft-ietf-mmusic-sctp-sdp section 9.3: " When an SCTP association is established, both SCTP endpoints MUST We have the same model in ORTC. In other words, local port == remote port. Thus you only need to have one value passed in as a parameter to the SctpTransport, not two. Just like SIDs for data channels. There's no need to have them be different and everything is simplified by having them be the same. By the way, this came up before: #227. |
When I'm reading this text, I come to a different conclusion. In order to prevent two separate SCTP associations being established, both peers need to connect by using the corresponding local port the other peer chose. They simply have to know each other's local port. However, there's no technical reason why these ports shouldn't be different. Not being able to choose a local port freely has implications on implementations that may have multiple SCTP connections using the same stack. Application 1 might have been established by the mutual choice of port 5000. However, now I'm using the same stack in the role of the answerer and I'm receiving an offer with We can easily work around this issue by letting both parties specify their local ports. It is a trivially solved problem (code-wise at least) compared to finding a proper solution for the issue raised in the previous paragraph. Also, one has to ask: If you're correct and this is the intended way, then why are both parties sending an SCTP port number in the offer/answer SDP? See draft-ietf-mmusic-sctp-sdp-20 section 10.2 and 10.3., especially the example in section 13.1. |
Yes, perhaps I did misread draft-ietf-mmusic-sctp-sdp. It's saying that it must listen on and connect with the same port, not that both sides need to pick the same local and remote port. However, it was the intention of the ORTC design to have the local and remote port always be the same. I suppose that means that ORTC as currently designed would not allow a full draft-ietf-mmusic-sctp-sdp implementation. But I'd go back to the same logic that I believe we had back then: it's not worth it the extra complexity in the API to be able to support different ports on each side. |
Given the example above, it seems like it might be worth the added complexity after all. Otherwise the application would need to negotiate to find a port that's not already in-use by either peer. |
The example give sounds like a problem in dctt that needs to be fixed, or some workaround found. It doesn't make sense to add extra complexity to the API and to all implementation of it just because of some limitation in dctt. In principle, there is no reason you can't use port 5000 in that example because it's all virtualized over a completely different DtlsTransport that isn't using port 5000 (in other words, the ports are scoped to DtlsTransports). It's just a limitation of dctt (which might have some other work around). So my answer would be to either fix dctt or find a work around. But don't add a bunch of complexity to everything else. |
dctt requires a relaying party that handles DTLS. The workaround is to change the port number (easy) at the relay station and recalculate the checksum (meh!) in the SCTP packet. Yes, it can be done but it's rather messy. And let's not forget that there might be other use cases in the future. I still believe it's worth the effort and there might be more parameters we want to exchange in the future that are not static (and then we'll have the same discussion again while WebRTC on the other hand can easily cope with it). It makes the API more consistent (as every other transport has parameters, why should it be different for SCTP) and I can't see any substantial changes implementation-wise either (at least in my implementation it was really easy). The SCTP INIT triggered by the constructor can simply be moved into the |
Perhaps your use case is different than I thought at first. It sounds like you want to communicate with an SCTP endpoint through a relay that terminates DTLS but not SCTP. Is that right? That sounds like a more reasonable use case. However, why is a simple solution not to just let that remote endpoint choose the port and use that port for both the local and remote port? I know that doesn't fit the SDP model without an extra round trip, but there's an easy solution for that: don't use SDP. If we did add something to make this easier, then I would be in favor of #2 (add another parameter to the constructor). It would be a simple enough addition and make this use case slightly easier. But I think option #3 is too much complexity being added for too little benefit. |
Yep.
Yes, I know that I'm stretching it a little bit with the following example: What if both terminate at a (possibly even the same) kernel stack? I don't know of a good use case other than for testing purposes but I can tell you that I've had this exact problem in the past and I had to work around it.
I still don't understand where the complexity for option 3 is. We only have do to very few changes to the API and existing implementations:
Edit: I can provide a PR to these changes if you want to see it in detail. |
If both endpoints are doing SCTP but not DTLS (and thus not ORTC), then where does ORTC fit into the picture? As for complexity, I don't think there's any issue with changing the INIT to be at start time (but I may have missed something). I'm mainly opposed to changing from a "caps" model to a "caps and params" or just "params" model. I'm not opposed to that in general (it works well for ICE and DTLS), but it does add complexity for both the user of the API and the implementer, and it's been nice to avoid that complexity for SCTP. The way you describe the addition is just the tip of the iceberg. There would be a lot more to it as we went to work out all the details and edge cases. There always is (and there was for ICE and DTLS). So we should only add it if there's a clear benefit. And I just don't see much benefit. The only benefit I see could be equally served by passing in the remote port to the constructor, which is a lot more simple. So if we're going to add anything, I think it should be the simplest thing that meets the use cases, which is option #2. |
Good question. I did this for testing purposes only (@tuexen asked me to write a low footprint test tool for WebRTC data channels and I simply chose to implement the ORTC API in C and handle all the SDP-related stuff in the browser using adapterjs, and while writing that I also tested dctt to dctt on the same machine). As I said, I have no real world use case other than that and we don't know what the future will bring us. Even though I understand your concern about the complexity a little better now, I still think option 3 would be the most adequate one for reasons I've already mentioned in the previous posts (API consistency, WebRTC compatibility (?), future-proofness). Independent from whatever consensus we reach here, I think we should raise an issue regarding draft-ietf-mmusic-sctp-sdp section 9.3 to further improve the wording there and to clarify which one of our interpretations is correct. |
I don't think draft-ietf-mmusic-sctp-sdp needs to change 9.3 to be more clear. But I did fail to find anywhere that said something like "the value of the sctp-port attribute in the remote description MUST be used as the remote port and the value of the sctp-port attribute in the local description MUST be used as the local port". But perhaps I just didn't see it. See if you can find it. If not, that's what I would suggest as clarification. |
In general, I have the feeling that your interpretation of section 9.3 could be the correct one but then it's not clear that the |
Just a possible clarification: When using the SDP stuff, each side uses a single SCTP port number. The two numbers can be different, they can be the same. Each side uses only its single port number for communicating with the peer (so not two number for the two roles: client and server). I don't think it is a limitation to require that both endpoints use the same port number, since the port numbers are only used to multiplex/demultiplex the SCTP connections running over a single DTLS connection. So if a port number is used over one DTLS connection, the same port number can be used over a different DTLS connection. They don't affect each other. |
In response to tuexen: You have a good point that in the case where there is only one SCTP connection over a DTLS connection, we don't really need to tell the local SctpTransport what port it will receive SCTP on, or even to assume it's the same it will send SCTP on, since there is only one SCTP connection anyway. If one wishes to have more than one SctpTransport over the DtlsTransport, then the remote port (or port if they are equal) needs to be known to demux. But it is an option to simply require that there be only one SctpTransport per DtlsTransport and thus the remote port is irrelevant. I recall some discussion at the IETF over whether or not anyone would want to have more than one SCTP association, and I recall the answer being that no one really needed it. Do you know if draft-ietf-mmusic-sctp-sdp allows for it or not? |
In draft-ietf-mmusic-sctp-sdp we considered multiple SCTP associations over the same DTLS association out of scope (https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-20#section-5.3). sctp-port attribute is required and only a single value of this attribute is allowed per m= line. There are no limitation on the values of sctp-port attribute (they can be the same or different on both sides), as long as they are non 0. While the same pair of values continues to be used, the same SCTP association should be used. Change of sctp-port value on either side of the connection will cause new SCTP association to be established. Setting sctp-port to 0, closes SCTP association. When implementing, sctp-port value should be set to a random number for a new SCTP association, and should be set to previous value to continue using the existing association. |
I'm sure I was asked at one point of time to make sure that you can use multiple SCTP associations over a single DTLS connection and made sure this works for DTLS/SCTP. However, I'm not an expert in SDP, but the above comment might answer your question. |
@tuexen I think it possible to make multiple SCTP associations to work over the same DTLS association, but we decide that this is going to be out of scope for the current specification. I think this was not needed for rtcweb, so we decided to skip this. |
I was referring to making sure it works in draft-ietf-tsvwg-sctp-dtls-encaps-09 and that is what I did. It was a requirement stated in a very early state of the WebRTC standardisation. It was a noop to provide this feature. I don't think it is used in WebRTC right now, so it is fine not to have it in the SDP spec. |
@tuexen It would probably be trivial to add this feature in the future revision of sctp-sdp specification. I think all this will require is an update for mux rules for sctp-port. Since we were under time pressure to publish, this was not done in the current version. |
@rshpount: As I said: That is fine from my perspective... |
The PR has already been merged, so I'm commenting here. This needs to go into
|
@lgrahl Right. I've moved the text (see http://draft.ortc.org/). |
👍 Can be closed from my side. |
If I haven't overlooked something, there's no way to determine the SCTP port of the remote peer.
For WebRTC, the remote port can be found in the offer/answer SDP.
I'm proposing to add the remote port to
RTCSctpCapabilities
as aremotePort
port
attribute.Furthermore, we should discuss whetherport
in the constructor should also be renamed tolocalPort
to avoid confusion.RTCSctpCapabilities
could be renamed toRTCSctpParameters
because an SCTP port is not really a 'capability'.Edit: I've withdrawn my suggestion to rename the attributes as other transports that provide parameters do not prefix the attributes with
local
orremote
either.Cheers,
Lennart
The text was updated successfully, but these errors were encountered: