Archive

Posts Tagged ‘MSRP’

MSRP Session Match Backwards Compatibility

May 24th, 2011by Ben Campbell under SIP

My last post described the MSRP Session Match extension (aka “sessmatch”) and its purpose. I mentioned that there were some backwards compatibility issues. This week I will discuss those issues in more detail.

The session matching criteria in sessmatch were intended to be backwards compatible with RFC 4975. Remember, sessmatch relaxes the session matching rules so that only the “session identifier” component of an MSRP URI is considered when matching an MSRP request to a session. An MSRP URI that matches a session according RFC 4975 (that is, an as an exact URI match) always also matches according to sessmatch. And as long as nothing modified an MSRP URI in the SDP offer and answer, then things will still match according to RFC 4975 rules.

But keep in mind that the whole point of sessmatch is to allow a device, for example an SBC, to modify the MSRP URIs in the SDP. So I think we can assume that, whenever sessmatch is used, something probably does modify the URIs.

As sessmatch was specified prior to version 11 of the draft, An MSRP endpoint that supports sessmatch, and is also behind an SBC, cannot talk to an endpoint that does not support sessmatch.

And even if both endpoints support sessmatch, things break down if one endpoint uses an SBC and the other uses an MSRP Relay. The sessmatch extension, as currently written, does not apply to MSRP relays. But relays use the same session matching rules as in RFC 4975. So if an SBC modifies the offer or answer, then the session will fail to match at the relay.

That problem could be mitigated if we extended sessmatch to apply to relays as well. But there’s still a more subtle problem. One very popular feature of SBCs is something called “topology hiding.” Topology hiding means that the SBC hides artifacts (such as IP addresses, host names, and URIs) that identify hosts on one side of the SBC from devices on the other side. This is done for a variety of reasons. Some providers believe their internal topology to be sensitive information. Some want to anonymize the IP addresses of their customers.

Topology hiding can be applied in any number of places. For example, it’s common to hide SIP Route, Record-Route, and Via header field values. But if an SBC performs topology hiding on SDP payloads, then MSRP relays will break.

An endpoint that uses an MSRP relay puts the entire MSRP path to the endpoint in its SDP path attribute. This may look something like the following:

a=path:msrp://relay.example.com:2855/asfd34;tcp msrp://bob.example.com:3464/siefkd938;tcp

MSRP Relays are session-stateless. They need this entire path in order to figure out where to route MSRP messages. But if a topology hiding SBC removes part of that path, the relay can’t deliver inbound messages. For example, the SBC might change the previous path attribute to look like this:

a=path:msrp://sbc.example.com:2855/asfd34;tcp 

Now when Bob’s peer tries to send an MSRP SEND request, it will probably get as far as Bob’s relay. But the relay will have no idea how to send it on to Bob.

Version 11 of the sessmatch draft recognizes the backward compatibility issues and proposes a new SIP option tag that indicates an endpoint both supports and is deployed in a way that it can actually use the sessmatch extension. This will at least allow endpoints to fail in a graceful way if their network policies prevent them from exchanging MSRP messages. In the best case, the endpoint behind the SBC could attempt to use an MSRP relay instead, or an SBC could change its behavior for the session to avoid incompatibilities. But in reality, providers that use an SBC in the first place are unlikely to allow such fallbacks as a matter of policy.

The option tag will help prevent the balkanization of the MSRP protocol itself. Unfortunately, the need for sessmatch in the first place shows that service providers, through incompatible policies and network designs, are likely to break the MSRP user communities into islands that can’t talk to each other.

More on MSRP Session Match Extension

April 12th, 2011by Ben Campbell under SIP

Last time, I mentioned that draft-ietf-simple-sessmatch, one of the few remaining milestones for SIMPLE, had some controversies associated with it. For the sake of brevity, I will refer to the extension described in that draft as “sessmatch.”

But before we get into the issues related to sessmatch, let’s discuss the problem it sets out to solve: Sessmatch is designed to make life easier for Session Border Controllers (SBCs) when handling MSRP. An SBC typically anchors media by rewriting the Session Description Protocol (SDP) to insert itself into the media stream. Each endpoint sees a media description that points to the SBC, rather than the peer endpoint. The SBC (hopefully transparently) relays media between the endpoints.

In the case of MSRP as defined in RFC 4975, this doesn’t work. The problem lies in the way an MSRP endpoint recognizes its peer. For example, Bob’s endpoint might send the following in an SDP answer to an offer from Alice:

a=path:msrp://bob.example.com:2855/asfd34;tcp

Alice opens a TCP connection to Bob, and sends an MSRP SEND request that contains the following URI in the To-Path header field:

msrp://bob.example.com:2855/asfd34;tcp

Bob’s endpoint knows this is Alice because it’s the URL he gave to Alice. (We assume Bob authenticated Alice in the signaling layer and used confidentiality protection.) The URI is designed to be hard to guess, so Mallory can’t easily send the same URI and pretend to be Alice. You can think of the URI as a shared secret between Alice and Bob.

But if there’s an SBC between Bob and Alice, the SBC has to rewrite the SDP in order to anchor the MSRP session. So Bob’s SDP answer gets changed to something like this:

a=path:msrp://sbc.example.com:2855/asfd34;tcp

Alice now opens a connection towards the SBC. Let’s assume for the moment the SBC then opens a connection toward Bob and relays packets from Alice to Bob. (The actual direction of connections may be more complicated if COMEDIA is used–but let’s ignore that for now.) The problem is, Alice now sends the following in the MSRP To-Path header field:

msrp://sbc.example.com:2855/asfd34;tcp

Bob doesn’t recognize that URI as the one he sent to Alice, so the session fails. The SBC could have kept state about the URI mapping, and rewritten the To-Path headers field value to match Bob’s expectation. But SBCs are usually large-scale devices, and this bit of work adds up to a lot over many simultaneous sessions. This is further complicated by the fact that many SBCs handle packet relaying in special purpose hardware. They quickly lose the hardware advantage when they have to apply a lot of processing to the relayed packets.

The sessmatch extension tries to mitigate this, using the fact that the only really hard-to-guess part of an MSRP URI is the session identifier. For example, Bob’s URI:

msrp://bob.example.com:2855/asfd34;tcp

… has a session identifier of “asfd34″. MSRP requires that identifier to be unique and hard to guess. The rest of the URI (the address, port, and transport) is actually pretty easy to guess. So if we treat “asfd34″ as the shared secret, that’s close to the same level of secrecy as you get with the whole URI. So if Bob supports the sessmatch extension, he doesn’t insist that Alice hands him the exact URI as he sent in the SDP answer. He only insists that the session id part is the same. The SDP rewrites the SDP to contain the following URI:

msrp://sbc.example.com:2855/asfd34;tcp

But since that URI contains the exact same session ID as Bob’s original URI, Bob can still use it to determine he’s really talking to Alice.

The apparent great thing about sessmatch is that this is backwards compatible with RFC 4975, in the case where no SBCs are present. If nothing rewrites the SDP offer or answer, then Alice still sends Bob’s original URI. This matches both under the original RFC 4975 matching rules and the sessmatch extension matching rules.

Unfortunately, when an SBC is present, there are some cases where this backwards compatibility breaks down. And these are real world cases that have been encountered by real-world implementors. I’ll present the details in my next post.

SIMPLE Working Group Update

March 1st, 2011by Ben Campbell under SIP

As I and others on this blog have mentioned on several occasions, the SIMPLE (or the more formal and rather awkward: “SIP for Instant Messaging and Presence Leveraging Extensions”) working group of the IETF has been responsible for defining how to do Presence and Instant Messaging applications using SIP and related protocols. The SIMPLE working group has existed for some time; in fact, it’s one of the oldest ongoing working groups in the Real-time Applications and Infrastructure (RAI) area of the IETF. I am currently a co-chair for SIMPLE.

I write to tell you that SIMPLE’s work is almost done. We are finally seeing the light at the end of this long tunnel. Of the four remaining work items, one is in the AUTH48 state. (This means that the RFC editor has presented a candidate for the final RFC version back to the authors for any last minute edits and approval.) One entered Working Group Last Call (WGLC) last week. There are only two work items that may still see controversy, and one of those is in IESG review.

These drafts are, respectively, draft-ietf-simple-msrp-acm, draft-ietf-simple-simpledraft-ietf-simple-msrp-sessmatch, and draft-ietf-simple-chat.

The first draft extends the MSRP protocol to allow the endpoints to negotiate which one will open a TCP connection to its peer. I blogged about this draft some time ago. We should see publication of the resulting RFC any day now. In fact, it’s already been assigned a number: RFC 6135. [Update: RFC 6135 was officially published on February 28.]

The second, draft-ietf-simple-simple (aka “SIMPLE made Simple”), is an informational draft that acts as a road-map and secret-decoder-ring for the various specifications produced by the SIMPLE working group. (Keep in mind, that there is no one protocol known as SIMPLE. But we still tend to use the term SIMPLE informally to refer to the resulting suite of protocols and architecture.) The fact that this draft is in WGLC means the author believes that this draft is essentially ready to be sent to the IESG for final review and publication. It’s possible that the last call review could uncover some controversial point that would require more work. But given the nature of this draft, I expect that any WGLC feedback is more likely be clarification and editorial comments.

We do know in advance, however, that draft-ietf-simple-simple may require minor editing to reflect the final disposition of the last two drafts below. This means that, regardless of its current completion state, draft-ietf-simple-simple will be the last draft to be published by SIMPLE.

Draft-ietf-simple-msrp-sessmatch describes an extension to MSRP to make it more friendly to Session Border Controllers (SBCs). The way that MSRP devices match TCP connections to message sessions means that, if an MSRP session traverses an SBC, that SBC has to re-write the To-Path and From-Path header fields in a manner similar to an MSRP Relay. Some working group participants expressed concern that this requirement could impact SBC performance. The sessmatch draft would allow supporting endpoints to work across SBCs that do not change MSRP messages en route. However, there are still ongoing discussions concerning the impact on security and interoperability.

Assuming that the sessmatch draft has not become a moot point by then, I plan to go into considerably more detail on it and the surrounding controversy in my next blog entry.

Then, finally, there’s draft-ietf-simple-chat. This draft defines how to create MSRP “chatrooms” with conference servers. There’s still some controversy over how this draft interacts with some similar work from the XCON working group.

Hopefully, we will resolve the issues around these last two drafts soon–at which time I hope to be able to entitle a blog entry as “SIMPLE Finally Done!”

The MSRP Report Model

June 9th, 2010by Ben Campbell under SIP

MSRP offers a highly configurable reporting model. The model offers two mechanisms for an endpoint to learn the status of the messages it sends.
 
The first, and simplest, mechanism is the transaction response to a SEND request. Here’s an example from RFC 4975:

MSRP a786hjs2 SEND
To-Path: msrp://biloxi.example.com:12763/kjhd37s2s20w2a;tcp
From-Path: msrp://atlanta.example.com:7654/jshA7weztas;tcp
Message-ID: 87652491
Byte-Range: 1-25/25
Content-Type: text/plain

Hey Bob, are you there?
——-a786hjs2$

MSRP a786hjs2 200 OK
To-Path: msrp://atlanta.example.com:7654/jshA7weztas;tcp
From-Path: msrp://biloxi.example.com:12763/kjhd37s2s20w2a;tcp
——-a786hjs2$

A SEND transaction response contains a status code similar to the status in a SIP response. Keep in mind, though, the semantics of each status code are not quite identical to those for SIP. In this case, the “200″ status indicates successful delivery. Since the To-Path and From-Path header fields each contain a single URI, we know this transaction was sent peer-to-peer. That is, there are no MSRP relays involved in this transaction. Also, notice that the To-Path and From-Path values are reversed in the response. Unlike SIP, which copies the From and To values from the request into the response without switching them, the To-Path and From-Path header fields in an MSRP response indicate the actual routing of the response.
Responses to SEND requests are sent hop-by-hop, rather than end-to-end. This is due, among other things, to the way that MSRP relays can re-chunk messages, as I discussed in a previous post. Responses for non-SEND methods are sent end-to-end.
If the sender doesn’t get the response within 30 seconds, it assumes the request failed. 
  
The hop-by-hop nature of SEND responses can be insufficient if MSRP relays are in the session path. How can the sender learn about the success or failure of a message once a relay has forwarded it downstream? For example, what if the relay gets a failure response from its next hop? For this scenario, the relay can send an MSRP REPORT request. Here’s an example:

MSRP dkei38sd REPORT
To-Path: msrp://alicepc.example.com:7777/iau39soe2843z;tcp
From-Path: msrp://bob.example.com:8888/9di4eae923wzd;tcp
Message-ID: 12339sdqwer
Byte-Range: 1-106/106
Status: 000 200 OK
——-dkei38sd$

A report request carries very similar information to the transaction response for a SEND request. Notice the “Status” header field, which carries the same sort of status code that you might see in a transaction response. The “000″ prefix indicates the status code is one of the ones defined in the base specification. This is an extension hook, where other specifications could create status code “name spaces” with different prefixes. Remember from my last post that a REPORT request reports status for a range of bytes, which may or may not line up with the range in any particular SEND request that the sending endpoint actually sent.
A REPORT request is a bona-fide MSRP request. However, MSRP devices do not send transaction responses for REPORT requests. They should never send REPORT requests in response to other REPORT requests. REPORT requests that include a failure code, aka “Failure Reports”, are sent from the reporting element all the way back along the session path to the sender of the original request. On the other hand, “Success Reports” are always sent end-to-end, since only the endpoint can no for sure that a message was delivered successfully.
This is all complicated by the fact that MSRP allows a great deal of configuration in the reporting model. When the sender creates a SEND request, it can independently select whether it wants to receive success reports and failure reports, on a per message basis. It does this by including the optional Success-Report and Failure-Report header fields. 
Success-Report can take a value of “yes” or “no.” Failure-Report can take those same values, plus the value of “partial.” The defaults are “no” for Success-Report and “yes” for Failure-Report
If the sender wants delivery confirmation, it sets Success-Report to “yes”. The default is “no”, so if the header is not inserted, success reports won’t be sent.
Along the same line, if the sender wants to suppress failure reports, it can set Failure-Report to “no.” But there’s a catch here–if Failure-Report is “no,” that also suppresses transaction responses to the request. That means there’s really no failure detection at all, other than what might be detected by TCP. That may be counter-intuitive, but it makes sense for some applications. Examples include system messages sent by an administrator or broadcast messages sent by an emergency services agency. It also may make sense for high volume applications where it would be too heavy weight to send all those responses, and the TCP layer provides sufficient reliability. Keep in mind that Failure-Report and Success-Report can be set independently, so you can suppress failure reports and transaction responses, but still request success reports.
Then there’s the really strange sounding mode, where Failure-Report is set to “partial.” This mode suppresses transaction responses just like if it was set to “no.” But it still allows failure reports. This lets MSRP elements opportunistically report any errors they learn about through other means. For example, transport layer errors by downstream devices.
I think this will be the last of my MSRP related posts for a while, unless readers have specific questions. Please feel free to ask questions in the comments section. Otherwise, I will move onto some new and different topic in my next post.

More on MSRP: Chunking

April 27th, 2010by Ben Campbell under SIP

As I mentioned in past blog entries, MSRP is designed to carry arbitrary content. Not only does that mean it can carry any type of data, or at least any kind that can be represented in MIME, it means it can carry arbitrarily large data. MSRP also lets you use the same TCP connection for multiple sessions.
The down side to this is that TCP always delivers data in the order sent. If you start sending a very large piece of content (say, video), but then need to send something else that’s very important, the recipient’s endpoint won’t be able to see the very-important-message until it completely receives the video. We call this head-of-line blocking. MSRP’s chunking feature lets you get around this problem by interleaving content over a single connection.
For the purposes of this discussion, let’s define the term “message” to mean a whole piece of content, in the form of a complete MIME object. That could be a short “text/plain” object, or it could be a huge “video/mp4″ object. A “chunk” is a piece of a message. That piece could be the whole message, which would be likely for the small “text/plain” message, or it could be just a fragment of the message. To break a message into chunks, you first encode the message. You take one “message” and cut it into pieces, instead of creating a bunch of smaller “messages.”
MSRP uses the “byte-range” header field for this purpose. The byte-range field tells you what portion of the message is in a particular chunk. It also tells you the overall size of the message. For example, in the case of a short message that is fully contained in one chunk, you might see the following:
This means the chunk contains bytes 1 through 100 out of a total length of 100. On the other hand, for a chunk from the middle of a bigger message the Byte-Range header field might look like:

Byte-Range: 4097-6144/65535

The sending endpoint puts each chunk into a separate MSRP SEND request. The receiving endpoint reassembles the chunks into a whole message by inspecting the Byte-Range headers. Both parties can use the total length value to provide progress information to the users. All the chunks from a given message share the same value in the Message-ID header field. 
Here’s an example of a SEND request containing an entire message:

MSRP d93kswow SEND
To-Path: msrp://bob.example.com:8888/9di4eae923wzd;tcp
From-Path: msrp://alicepc.example.com:7777/iau39soe2843z;tcp
Message-ID: 12339sdqwer
Byte-Range: 1-16/16
Content-Type: text/plain

Hi, I’m Alice!
——-d93kswow$

And here’s an example of a message broken into two chunks:

MSRP d93kswow SEND
To-Path: msrp://bobpc.example.com:8888/9di4eae923wzd;tcp
From-Path: msrp://alicepc.example.com:7654/iau39soe2843z;tcp
Message-ID: 12339sdqwer
Byte-Range: 1-137/148
Content-Type: message/cpim

To: Bob
From: Alice
DateTime: 2006-05-15T15:02:31-03:00
Content-Type: text/plain

ABCD
——-d93kswow+

MSRP op2nc9a SEND
To-Path: msrp://bobpc.example.com:8888/9di4eae923wzd;tcp
From-Path: msrp://alicepc.example.com:7654/iau39soe2843z;tcp
Message-ID: 12339sdqwer
Byte-Range: 138-148/148
Content-Type: message/cpim

1234567890
——-op2nc9a$

But sometimes, the sender may not know the size of the entire message in advance. For example, imagine that the sender is capturing video from a webcam. It would be inefficient to wait until the entire video is captured to start sending. If you don’t know the full message length, you can put a “*” in the total size field. For example:

Byte-Range: 4097-6144/*

Chunking is very useful, but it adds overhead. You really want to avoid chunking a message unless you have a good reason. Chunking was envisioned for situations where an endpoint needs to send a high priority message when a large message is already in the process of being sent. For example, the peer device might send you a message that requires a timely response in the form of an MSRP REPORT request–but you’ve already got a large transfer in progress. You can’t wait for the large transfer to complete first. The problem is, you can’t know in advance that this will happen, so how do you decide whether to break the large message into chunks? MSRP allows you to interrupt an in-process SEND request. 
The last line of a SEND request is known as the end-line. The end-line is made up of seven hyphens, followed by a transaction identifier and a continuation flag. The transaction identifier is a random sequence initially written into the start line (look closely at the second field in the start lines of the examples above–they repeat in the end-line. The continuation flag tells you whether there are more chunks in the message. If it contains a “+”, then the recipient knows to expect more chunks. If it contains a “$”, then it’s the last chunk in the message. It can also contain a “#” to indicate the sender is abandoning the message.
You can make a SEND request interruptible by putting a “*” in the end-range field in the Byte-Range, like so:

Byte-Range: 4097-*/65535

In this example, the sender could start sending the entire 65535 octet message in a single SEND request. But if it needs to interrupt the message part way through, it simply writes out the end-line, and puts a “+” in the continuation field. It then sends whatever high-priority message that forced the interruption, then resumes the original large message in a new chunk. The receiver cannot tell the actual end-range from the Byte-Range header. Instead, it has to calculate the end-range by counting the actual number of octets before the end-line, and adding that to the start-range value.
A common misconception about MSRP is that the specification says that any message larger than 2048 octets must be broken into chunks. It really says that any message larger than that must be interruptible. It’s far more efficient to send a large message in one interruptible chunk than in a bunch of small chunks. That way you don’t incur the chunking overhead unless you really need it.
There’s another aspect of MSRP chunking that can make the implementer’s life interesting. If there’s an MSRP relay in the path of a session, that relay can break a chunk into smaller chunks. It can also reassemble several smaller chunks into a bigger chunk. This is transparent to the sender, except for one thing.
MSRP allows the recipient, or an intervening relay, to optionally send delivery reports in the form of REPORT requests. A REPORT request also contains a Byte-Range header field. In this case, the Byte-Range header field tells you the range of the original message to which the report applies. Since an intervening relay can change the chunking for a given message, the sender cannot assume that REPORT requests will line up with the chunks it actually sent. For example, you could send 3 chunks for the byte ranges of 1-33, 34-66, and 67-100, but get back REPORT requests for the ranges of 1-50, and 51-100. 
I think that’s enough for now. Next time, I will cover more details on how those REPORT requests work. But until then, here’s a forewarning: The REPORT mechanism is more complicated than you probably expect. 

New MSRP Standards Work: The Alternate Connection Model

March 17th, 2010by Ben Campbell under SIP

Even though the SIMPLE working group published the MSRP and MSRP Relay specifications some time ago, it’s not quite time to say we’re finished and go out for a beer. Like any new protocol, it has some rough edges that need to be polished out. SIMPLE is currently working on a bit of polish known as the MSRP Alternate Connection Model, or MSRP-ACM for short.

MSRP runs over reliable, connection-oriented protocols such as TCP. One important aspect of these protocols is that when two devices want to talk, one of them must act as a client and the other a server. That’s not as big a deal as it sounds. It merely means that the client opens the transport connection towards the server, and the server listens for and hopefully accepts the client’s connection. For truly client-server protocols such as HTTP, this makes perfect sense–your web browser opens a TCP connection to the web server. It rarely makes sense for the server to open the connection towards the browser.

Since so many application protocols work this way, the client-server assumption has become intrinsic to the way people build access networks. Chances are, there’s a firewall between your web browser and the server for this blog. There’s likely even a Network Address Translator (NAT). Both of these devices are commonly configured with policies that lets clients open outbound connections, but severely restrict who can open or receive inbound connections. 

But the client-server assumption falls down for many real-time communication applications. These applications are peer-to-peer at their cores, i.e. they are designed to allow any device to connect to any other device. It’s hard to deploy peer-to-peer applications on networks that were built for client-server applications. That mismatch has provided grist for many of the posts on this blog. I’m sure it has caused headaches for many of our readers.

As I mentioned in my last post, MSRP assumes that the peer that sent the SDP offer always acts as the TCP client. That is, it opens the transport connection towards the peer that sent the answer. For this reason, we often refer to the offer as the “active party.”

The active party also must immediately send an MSRP SEND request to its peer. This is because when the listening device (aka the “passive party”) receives a connection, it doesn’t know for sure who’s really trying to connect. When it receives the SEND request, it can compare an MSRP URI in the request to the one it sent in the SDP answer. You can think of that URI as a party invitation the active party must present to get in the door.

But making the offerer into the active party does not work in all possible scenarios. Let’s go back to the usual suspects, Alice and Bob. Alice sends the SDP offer to Bob, making Alice into the active party and Bob into the passive party. But Bob is behind a NAT that doesn’t allow inbound connections. They need an MSRP relay, or some other kind of media relay, to talk at all.

But what if Alice was not behind such a NAT? They would have been able to talk just fine if Bob sent the offer to Alice. It seems a shame to require the overhead of a relay, if Alice and Bob could have solved the problem by reversing roles.

COMEDIA describes a set of SDP extensions for negotiating which peer becomes the active party for connection oriented media. The MSRP-ACM draft describes how to apply COMEDIA to MSRP sessions, instead of just using the default assumption that the offerer is always the active party.

So if Alice and Bob had both supported the alternate connection model, Alice would have declared in the SDP offer that she could act as either the active or the passive party, since she was not behind a NAT.  Bob would respond in his SDP answer that he could only be the active party. Bob would then take over the role of active party, even though he was not the offerer. He would then open the TCP connection to Alice, and send the initial SEND request.

This situation may not occur very often for sessions between end users. It’s far more likely that both parties have NATs or firewalls getting in the way, and you still need at least one party to use an MSRP relay or other NAT traversal technology. But MSRP-ACM can be extremely useful if one party is an application server, such as a conference bridge, offline message server, etc. It’s much more common for such server-class devices to be able to accept inbound TCP connections. But if they MSRP without MSRP-ACM, then they would need a relay in order to initiate a session to an end-user. With the alternative connection model, that’s no longer necessary.

The SIMPLE working group is almost finished with the MSRP-ACM draft. The draft has completed working group last call (WGLC). The draft authors are working to resolve some WGLC comments, after which the group will submit the draft to the Internet Engineering Steering Group (IESG) for final evaluation before it becomes an RFC.

 

MSRP Target Path

February 3rd, 2010by Ben Campbell under SIP

My last post described how MSRP endpoints use SDP to setup sessions. Today, we’ll discuss how the MSRP protocol uses the results of the SDP offer/answer exchange.

Each endpoint builds a “target path” that it will use for all MSRP communication with its peer. If an endpoint does not use a relay, then the target path is exactly the same as the SDP path attribute value it received from its peer. On the other hand, if the endpoint does use a relay, then it forms the target path by prepending the URI that it got from each relay to the peer’s SDP path attribute value. In both cases, the target path form a roadmap of how to get an MSRP request to the peer, i.e. a list of MSRP URIs showing each hop to visit on the way, ending with the URI of the destination device.

If you recall from last time, Alice sent Bob an SDP offer containing the following:


a=path:msrps://alice.example.com:7654/asfd34;tcp

Bob responded with an SDP answer containing this:


a=path:msrps://relay.example.net:8211/asfioef;tcp msrps://bob.example.net:6581/asfd34;tcp

Since Alice didn’t introduce a relay (Bob’s relay doesn’t count here), she’s got life easy. Her target path is exactly what Bob sent her:


msrps://relay.example.net:8211/asfioef;tcp msrps://bob.example.net:6581/asfd34;tcp

 
Okay, I lied a little bit about Bob’s relay not counting. The relay clearly exists in the path, because Bob put it there. But since Alice did not introduce a relay on her own behalf, she uses Bob’s path value as-is, without worrying about relays in general.
 
On the other hand, Bob did introduce a relay. So to get his target path, he takes the path Alice sent him, and prepends his own relay, and gets this:
 


msrps://relay.example.net:8211/asfioef;tcp  msrps://alice.example.com:7654/asfd34;tcp

 

Alice and Bob are now almost ready to exchange MSRP messages. But there’s one more step that must happen first. Alice must open a TCP connection towards Bob. Note that RFC 4975 says the offerer always opens the connection towards the answerer. There’s work afoot to allow MSRP endpoints to negotiate the connection direction using COMEDIA, but for now lets assume Alice and Bob are using RFC 49752 as-is.

Alice connects to the first device in her target path. In this case, that’s Bob’s relay. She uses the DNS to get an IP address for “relay.example.net” and opens a TCP connection to port 8211, and starts sending messages. That’s assuming she doesn’t already have such a connection–for example, she might already have an MSRP session in progress with someone else that uses the same relay as Bob. In that case, she just uses the connection she already has.

Now, lets pretend for just a moment that things were reversed, and Bob had sent the original offer. The first device in his target path is also “relay.example.net”. But since he already set up a connection to that relay when he authenticated with it, he doesn’t need to setup a new one. He just reuses the one he already has. The relay would establish a connection to the next hop (Alice, in this case) on demand.

When either endpoint wants to send a message to the other, it constructs a SEND request with the message content in its payload. The endpoint puts its target path in a To-Path header field, and its own URI in the From-Path header field. It then sends the request to the first device in the To-Path. If that device is the peer, then that’s pretty much all there is to it. If the first device is a relay, the relay removes its own URI from the To-Path and prepends it to the From-Path, then relays the request downstream.

Here’s a picture for Alice and Bob. I’ve replaced the actual URIs with the symbols “Alice”, “Bob”, and “Relay” to try to keep it readable.

To-Path and From-Path 

At this point, you are probably (and rightly) wondering what the point of a relay moving its URI to the From-Path header field when it relays a request. This allows a downstream device to send a response to a SEND request, in the form of a REPORT request. Don’t confuse this with a message from the human Bob in response to a message from the human Alice. That would simply be another SEND request in the opposite direction. Instead REPORT requests carry delivery information about the original request.

The peer device, and any relays in between can originate a REPORT request back to the endpoint that sent a SEND request. They do this by inserting the From-Path that they observed in the Send request into the To-Path of the REPORT request. Here’s a picture showing a REPORT request sent by Bob, and another by Bob’s relay.

REPORT Paths

That’s enough for now. Next time, I’ll talk about how MSRP messages can be broken into “chunks” in order to multiplex multiple sessions across the same connection. 

 

 

 

MSRP SDP Extensions with Relays

December 22nd, 2009by Ben Campbell under SIP

My last SIP Sessions post discussed the SDP offer/answer extensions used by MSRP in the peer-to-peer scenario. Today, we will look at how this changes when you introduce MSRP Relays into the mix.

RFC 4976 defines the MSRP relay extension. There’s quite a bit to talk about with MSRP Relays. Today we’re going to focus just on the parts that impact the offer/answer process. I’ll cover more about relays in a future post.

An MSRP client that needs to use an MSRP relay must first authenticate to the relay and request an MSRP URI that represents the session at that relay. It does this using an MSRP extension method called “AUTH”. We will dive into the gory details of AUTH after we discuss the general MSRP transaction model–also in future posts (Are you starting to see the pattern here?). But we need to understand it conceptually in order to explore how relays affect the offer/answer model.

The client sends the AUTH request to the relay over a TLS connection. The relay authenticates the client using a form of digest authentication much like that from HTTP and SIP. The client uses the TLS association to authenticate the relay.

Once the authentication completes the relay generates an MSRP URI that resolves to the relay itself. The relay puts this URI in a “Use-Path” header field in the 200 OK response that it sends back to the client in response to the AUTH request. The client then uses the relay’s URI in the session negotiation.

This is conceptually similar to how some other relay-based NAT traversal mechanisms work. For example. SOCKS and TURN each allow a client to request a relay device allocate a port on its behalf.

Once the client gets a “Use-Path” header value from the relay, it can then build the SDP path attribute by appending its local URI to the relay URI. For example, assume the client’s URI is “msrps://client.example.com:2855/asfd34;tcp” and the relay returned a Use-Path value of “msrps://relay.example.com:7212/d3asdf43;tcp” The path attribute would now look like the following: 

a=path:msrps://relay.example.com:7212/d3asdf43;tcp msrps://client.example.com:2855/asfd34;tcp

You’re probably wondering why “Use-Path” is not called “Use-URI”. The reason for this is, just like the SDP path attribute, “Use-Path” can contain more than one URI. There are few cases where a relay might need to return more than one URI. (You guessed it–we’ll talk about those in a future post.) But regardless of why it might happen, the relay-using client would build the SDP path header by taking the entire contents of “Use-Path”, reversing it, then adding its own URI to the end. Thus, the SDP path attribute becomes an assertion to “to get to me, follow this path from left to right. My local URI is on the end.”

Let’s look at a more complete example from RFC 4976. Alice invites Bob to an MSRP session. Alice does not use a relay, but Bob does. Alice’s offer looks something like the following:

v=0

o=alice 2890844526 2890844526 IN IP4 alice.example.com

s= 

c=IN IP4 alice.example.com

t=0 0
m=message 7654 TLS/TCP/MSRP *
a=accept-types:text/plain
a=path:msrps://alice.example.com:7654/asfd34;tcp

When Bob sees the offer, he connects to his relay (relay.example.net), and performs an AUTH transaction. He gets back a 200 OK response containing, among other things, the following:

 Use-Path: msrps://relay.example.net:8211/asfioef;tcp

Bob’s SDP answer then looks something like this:

v=0

o=bob 2890844542 2890844542 IN IP4 bob.example.net

s= 

c=IN IP4 bob.example.net

t=0 0
m=message 6581 TLS/TCP/MSRP *
a=accept-types:text/plain
a=path:msrps://relay.example.net:8211/asfioef;tcp msrps://bob.example.net:6581/asfd34;tcp

Note that in this case, Alice’s client does not have to implement RFC 4976 at all. It won’t know how to use the AUTH method, but even basic RFC 4975 clients can still talk to relay-using peers.

That’s enough for now. Next time, we will talk about how these SDP path attributes get used inside MSRP proper.

SDP Extensions for MSRP

November 11th, 2009by Ben Campbell under SIP

This is my second in a series of posts about MSRP, or the Message Session Relay Protocol. My previous entry gave an overview of MSRP.
Like most other types of media that one can negotiate using SIP, you use the Session Description Protocol (SDP) Offer/Answer model to negotiate MSRP sessions. But MSRP is different in several ways than RTP, and these differences require some different approaches in SDP.
First, MSRP allows multiple sessions to use the same TCP connection. This means you can’t identify a session by IP address and port alone like with RTP. To get around this problem, MSRP defines its own URL scheme. Here’s an example:

msrp://host.example.com:2855/asfd34;tcp

In this example, “host.example.com” identifies the host. In this case, the host was identified by name–this could just as easily been an IP address. The port is “2855″, and the session identifier is “asfd34″. The unvalued “tcp” parameter merely means that this session uses TCP. (Right now, all MSRP sessions use TCP. It could work with other reliable stream oriented transports, such as SCTP, but the IETF has not yet defined bindings for any but TCP.) Just like what the IP address and port do for RTP, the MSRP URI defines where a device wants to receive media. A given session has a separate URI for each endpoint.
You can also specify the use of Transport Layer Security (TLS) by using a URI scheme of “msrps”.
Since the SDP m-line syntax does not support the transfer of URIs, MSRP defines an SDP media-level attribute called “path”. A path attribute for our example would look like the following:

a=path:msrp://host.example.com:2855/asfd34;tcp

It’s called “path” because it can actually carry more than one URI. This is useful when an MSRP session crosses one or more relays. We’ll talk more about that when we cover MSRP relays in a later post.
We do not ignore the m-line and c-line completely. MSRP endpoints copy the host from the URI into the c-line, and the port into the m-line. The peer doesn’t use those fields–it looks at the path attribute instead. The fields are copied just in case something in the middle cares about them, and doesn’t understand the MSRP specific extensions. Finally, the m-line media field is set to “message”, the proto field to “TCP/MSRP”, and the fmt list to “*”. The first two identify the session as MSRP. Here’s an example:
 

c=IN IP4 host.example.com
m=message 7654 TCP/MSRP *

 
The m-line fmt field is ignored because MSRP has another extension attribute to describe allowable content formats: accept-types. The accept-types attribute carries a list of MIME format types that an endpoint understands, in order of preference. It can also include a “*” entry, meaning all types are acceptable. The following example indicates an endpoint is willing to accept any type, but prefers plain text or HTML:

a=accept-types:text/plain text/html *

There’s also an “accept-wrapped-types” attribute, which is useful when you want to require the use of some envelope type such as “message/cpim”, but still negotiate the formats allowed inside that envelope. Use of “accept-wrapped-types” can get a bit complicated for this blog posting. If you’re interested, please see the RFC.
Here’s an example to tie it all together. Notice that the lines I didn’t mention are treated the same as for any other media type.

v=0

o=alice 2890844526 2890844526 IN IP4 host.example.com

s= 

c=IN IP4 host.example.com

t=0 0
m=message 7654 TCP/MSRP *
a=accept-types:text/plain
a=path:msrp://host.example.com:7654/asfd34;tcp

   
That’s enough for today. Next time, we’ll discuss how the negotiation works with relays involved.

<% Response.Write("" & vbcrlf) %>