The current msn_p2p design is good, but I think it could be improved and session handlers. Also, writing this helps me focus on the protocol design, understand it better, and make less mistakes.
Assumptions:(1) MSNSLP is MSNP2P version of SIP (Session initiation protocol). As a session initiation protocol, it is used to initiate transfers. The most common SIP methods used in MSNSLP are INVITE and BYE, but there are others such as ACK[1]
(2) Both MSNSLP and sessions itself are transferred inside a binary "envelope" (48 byte binary header + content + 4 byte footer) that adds information about the message itself (see point 3) and limits the size of the message (allowing to split it, see point 4)
(3) MSNSLP messages are SessionID 0, while other messages include a corresponding SessionID.
(3.1) MSNSLP message sequences are identified by the Identifier fields.
(3.2) The identifier sequences may or may not start at BaseID - 3 and skip BaseID[2]. The identifiers may not be repeated or may follow a strict sequence that varies between different transfer types.
(4) Binary headers include two fields, total data size and offset (IIRC), that are there to handle multipart messages better. Common examples of multipart messages include long file transfer invites (with preview data in base64 in the context field) and transfer data itself.
Current implementation:- Switchboard receives messages
- It parses binary headers and checks if it is a invite with a simple find()-like function.
- If it is an invite, checks in the binary header if is it complete or should be continued. If it is complete or if it completes a sequence of previous invites, it emits the invite signal which (often) creates a handler derived from msn_p2p.Base, such as Sender or Receiver.
- If it is not an invite, emits the message received signal.
Proposals(1) Separate MSNSLP handling from "session established" handling. I suggest checking with SessionID == 0, but it may be wrong.
(1.1) BYE messages should disconnect the corresponding session handler. Another signal
(1.2) Automatic binary acknowledges.
(2) Have real SIP parsers.
(2.1) The first line should be parsed not matched with find().
(2.2) We should be able to handle unknown MSNSLP methods / content types / EUF-GUIDs.
(2.3) The SIP message body would be handled according to the content type field in the SIP header.
(3) Efficient merging of multipart messages.
(3.1) Move it out of switchboard. I'm not sure where, maybe a "binary envelope layer".
(3.2) It should apply to all messages, specially data.
(3.2.1) The Buffer class is based on string concatenation, that is slow.
(3.2.2) Session handlers shouldn't receive and parse a message every time a chunk is received.
(3.2.3) Add a signal to tell session handlers (specially receivers) that a multipart message is received, with the binary header as parameter only. Each session handler would check the flag and the SessionID, which is a very quick task.
Related wishes* Be able to see a file transfer invite before the invite transfer is complete (i.e. huge context field)
* Be able to see the preview image as it loads. (96x96px)
* Inform the user about the progress on receiving other user's avatar (must be a plugin, but support on msnp2p is required)
Open issues* Differences between transfers. DP-ish transfers negotation is more complex than FT's.
* Differences between client versions.
* Check if, independently of the sequence (-3 or +1 always), the official client increases identifiers globally or per session.
Footnotes / References[1] There is some weirdness described on kmess developers blogs. They have implemented direct connection, and it seems that their msn p2p implementation is complete.
http://www.codingdomain.com/blog/archives/16-KMess-file-transfer-fixes;-MSN-Protocol-goodies.html[2]
http://monkey-messenger.blogspot.com/2007/06/status.html