# SIP2 Stack Design Document

2002-09-22
David
A.
Bryan
&jni;
dbryan@jasomi.com
Alan
Hawrylyshen
&jni;
alan@jasomi.com
Rohan
Mahy
&cisco;
rohan@cisco.com
Cullen
Jennings
&cisco;
fluffy@cisco.com
Jason
Fischl
&cathay;
jason@cathaynetworks.com
David
Butcher
&cathay;
david.butcher@cathaynetworks.com
Derek
MacDonald
&cathay;
Derek.MacDonald@cathaynetworks.com

1.0
2002-09-28
abh
Initial Porting to DocBook XML format.

## About this Document

### Feedback

Comments on this Guide may be directed to the &stack-name; team mailing list at &stack-list;.

### Copyrights and Trademarks

Copyright 1999-2002 David Bryan, Cullen Jennings, Alan Hawrylyshen, Jason Fischl, David Butcher, Derek MacDonald, Rohan Mahy

License for document goes here.

## Overall Information / Guiding Principles

The new stack will attempt to be &R3261; compliant in all cases.

The new stack will attempt as much as possible to delay parsing. Headers will not be parsed until we need them, and as little of the message will be parsed as needed to get us to that stage. Headers will simply be stored as strings until a parse is requested, at which point the actual contents of that header will be parsed into individual accessible storage containers.

## Design Details

### Preparsing

The new stack utilizes a pre-parser/parser structure. A preparse pass splits the message headers out, identifies the message type, and stores the body, but does not parse the individual components of the headers. That is left for the later header parser component. This paradigm is similar to approach taken by Apache.

### Receive Section

Not clear to me what the boundary between the transport and the pre-parse is ( need to clear that up here (class breakup).

The UDP transport (class name?)UdpTransport receives the data from the socket, and passes the information to the preprocessor (class name?).Preparse. This logic is responsible for several early parse activities. First, this code locates the start line in the message and decodes it, determining what type of message has been received. The code looks at each line, and if it finds a CR-LF it assumes that that line forms a new header. An order oneO(1) algorithm is used to map the header field name into an enumerated header type for all known header types. (describe algorithm). The constructors for these HFVs take a pointer into space owned by the SipMessage class. Unknown header types are stored as unknown headers, which can be accessed by the string name of the header later.

The body of the headers is passed to the SipMessage class, which adds it to a list of HeaderFieldValues (HFV). These HeaderFieldValues do not parse the actual content of the header at the time the message is received. Instead, they maintain a pointer and a length back into the message buffers in the SipMessage class that the message was received into. These HeaderFieldValues are only evaluated at the time the data within them is requested.

When messages are received, it is possible that they will be fragmented across several messages. Since a header can span a fragment for the messages, we need to merge the data if the header spans the boundary of two receives, but want to do minimal copies (we don't want to coalesce the buffer into a single buffer after all fragments are received)

In this case, the fraction of the message from the start of the fragmented header to the end of the message is copied into a new buffer, and the next chunk is read from the transport into that buffer starting at that point, and when that fragment is parsed, that HFV is generated with the complete header value in the new message. (see below).

#### Transport Chunking

The actual memory buffer(s) in which the messages live are owned by the SipMessage class, and do not ownership does not pass to the HFVs. The SipMessage class needs to keep a list of these headers, and ensure that they are properly destructed when they are no longer needed. More information is available on this in the data structures section.