Protocols/MSNP/MSNC/MSNSLP

From NINA Wiki
Jump to navigation Jump to search
MSN Client Protocol

MSNSLP

With MSN Messenger 6 a new sort of protocol is introduced and is based on SIP (Session Initiation Protocol). SIP is explained in RFC2543. MSNSLP is pretty much the same as SIP, but supports less request methods.

MSNSLP uses only the INVITE, BYE, and ACK methods, the latter only used in messages with content type application/x-msnmsgr-transudpswitch. If you are sending an unknown method, then the other client only sends its BaseIdentifier and nothing else after it.

MSNSLP structure

MSNSLP messages follow this structure:

  • start line\r\n
  • message-header-1: header value 1\r\n
  • message-header-2: header value 2\r\n
  • ...
  • message-header-n: header value n\r\n
  • \r\n
  • message body of zero or more bytes
  • NUL (\0)

Start Line

If it is a request, the start line will be a request line and will look like this:

method SPACE MSNMSGR:buddy@mail.com SPACE version \r\n

The method field is either INVITE to start a session and BYE to end a session. If you receive a second INVITE message in a session, then it's used to change the session parameters, you should accept it if everything is okay.

The version is currently MSNSLP/1.0


When not a request, the start line is a status line consisting of the protocol version followed by a numeric status code and its associated textual phrase, with each element separated by space characters.

version SPACE status code SPACE reason phrase \r\n

The status code is a 3-digit integer result code that indicates the outcome of the attempt to understand and satisfy the request. Your client must read the status code to determine whether this is a 200 OK or for example a 404 not found.

Message Header

Among the message headers are always in the following order these:

  • The To and From fields contain the email addresses of the receiver and the sender in the following format: <msnmsgr:mail@hotmail.com> where mail@hotmail.com is the email address of a person. Also this line makes clear that the user is using MSN Messenger, which can be determined on the "msnmsgr" part.
  • The Via field indicates what path was taken by the request, it's always MSNSLP/1.0/TLP ;branch={BranchUID} where "MSNSLP/1.0" is the protocol used and it's version and "{BranchUID}" is the unique identifier for that message.
  • The CSeq field is the "Command Sequence" field, most of the time this fields value is 0, but when you receive an incoming INVITE, you should always reply with the CSeq field of the incoming INVITE plus 1.
  • The Call-ID field uniquely identifies a particular invitation, and the Call-ID's of all other requests and responses to this user should have the same value. This fields value should be a GUID, but after some research I saw that it could have any value also non-GUID look-a-like values.
  • The Max-Forwards field may be used to limit the number of proxies or gateways that can forward the request to the next underlying server. But at the moment it isn't used by the MSN Messenger 6 client and servers, I think it can be used when Microsoft introduces its new Office Live Communications Server codenamed Greenwich. But at the moment the value is always zero.
  • The following line is the Content-Type line and specifies of which type the content is. For requests it can have the value application/x-msnmsgr-sessionreqbody or application/x-msnmsgr-transreqbody and for responses application/x-msnmsgr-sessionreqbody or application/x-msnmsgr-transrespbody.

When you receive an incoming message, you certainly need to check some fields whether or not they have the right values. If some data is missing or wrong, you should always send an error back. For further information read the error handling section of this document. The fields of the message header which you certainly should check are the To, the Content-Type and the Content-Length.

Message Body

The message body depends on the type of data requested and it must always have a NUL (\0 character) appended to it at the end. For information about the content of the message body see the relevant sections.

MSNSLP messages

INVITE Request

A message with INVITE as method can represent two things, namely a request to start a session or a request to change the sessions parameters. But in both cases most of the field have the same value.

Starting a session

When you want to start a session over the server, you should set the Content-Type to application/x-msnmsgr-sessionreqbody and you should add the following content fields: EUF-GUID, SessionID, AppID, Context

  • The EUF-GUID field determines whether this is an invite for a file transfer, custom emoticon or display picture.
  • The SessionID field contains the SessionID the rest of the session should use.
  • The AppID field contains the Application Identifier, this is also used to determine the type of the invitation.
  • The Context field contains a base64 encoded string of the MSNObject if it's an invite for a display picture or emoticon, or preview data if it's an invite for a file transfer.

Starting a transfer session

When you want to transfer something to the other client, you should set the Content-Type to application/x-msnmsgr-transreqbody and you should add the following content fields: Bridges, NetID, Conn-Type, UPnPNat, ICF

  • The Bridges field gives the other client a list of the available transport layers which the client supports.
  • The Conn-Type field tells the other client whether it's behind a Firewall, Symmetric-NAT, an Unknown-Connect or a Direct-Connect.
  • The UPnPNat field tells the other client whether it has UPnP-NAT enabled (true) or not (false).
  • The ICF field tells the other client whether it has the internet connection firewall enabled (true) or not (false).

BYE Request

To end an active session, you should always send a message with "BYE" as method to the other client. The Content-Type should have the value application/x-msnmsgr-sessionclosebody, the content should then be two times a CRLF. Also, if the session parameters where changed, you should just send one message with BYE as method.

Error Responding

When you receive an MSNSLP message, if some data is missing or wrong you should always send an error back. But in some cases errors are used to indicate that something processed with success or that a file transfer was declined.

If the value of the "To" header contains email addresses which isn't yours, you should reply with a 404 Not Found on the status line. The "From" should have the value <msnmsgr:wrong_mail@hotmail.com> where wrong_mail@hotmail.com isn't your email address. The Content-Type should be null and it shouldn't have content, so the Content-Length is zero.

If the Content-Type of the message received is not supported by your client, you should reply with a 500 Internal Error on the status line. The Content-Type should be null and it shouldn't have content, so the Content-Length is zero.

If some fields in the message body contain a value you don't agree with, you should also reply with a 500 Internal Error on the status line, but the Content-Type should have the same value as the received message. The message body should now only have the field SessionID with the identifier of the session as value.

Status line codes

200 OK

There are two different messages with 200 as Status-Code, namely one to accept an Invitation for a session via the server and one to accept an Invitation for a direct session between two clients.

If it's a reply to accept an Invitation for a session via the server you should generate a new BranchUID and add it to the ";branch=" text. You should also set the value of the "Content-Type" to "application/x-msnmsgr-sessionreqbody". And you also have to put the "SessionID" field into the Message Body with the Identifier of the Session as value.

If it's a reply to accept an Invitation for a direct session between two clients, you should then also generate a new BranchUID and add it to the ";branch=" text. But now the Message Body contains more fields. The field it contains are: "Bridge", "Listening", "Nonce", "IPv4External-Addrs" and "IPv4External-Port" or "IPv4Internal-Addrs" and "IPv4Internal-Port" or "IPv4ExternalAddrsAndPorts" or "IPv4InternalAddrsAndPorts" or "IPv6-Addrs" and "IPv6-Port" and "IPv6-global".

The "Bridge" field tells the other client which transport layer was chosen.

The "Listening" field tells the other client if it is already listening on the port and IP-address specified.

The "Nonce" field value is being used by the other client to "Authorize" itself via the direct connection.

If the client is behind NAT, the "IPv4Internal-Addrs" and "IPv4External-Addrs" fields contain the local and public IP-address. If the client is not behind NAT the "IPv4Internal-Addrs" field contains the public IP-address.

The "IPv4Internal-Port" and the "IPv4External-Port" fields contain the port to which you need to connect.

IMPORTANT: At the time of writing no further information is known about the IPv6 fields nor the "IPv4ExternalAddrsAndPorts" and "IPv4InternalAddrsAndPorts" fields, if you have information about that, please edit this page.

603 Decline

When you receive an Invitation for a file transfer, you can choose to decline the Invitation. This can be done by sending a "603 Decline" message to the other client. After receiving the Invitation you should send a 603 Decline message instead of a 200 OK message. Also, you should not create a new BranchUID but add the one from the Invitation message to the ";branch=" text. You should also set the value of the "Content-Type" to "application/x-msnmsgr-sessionreqbody". And you also have to put the "SessionID" field into the Message Body with the Identifier of the Session as value.