siplib.io

a modern and powerful library for parsing & manipulating SIP messages

siplib a powerful SIP library for framing & parsing SIP messages with a fluent API and immutable objects. siplib is part of pkts.io and the Aboutsip family and is designed to be used as a standalone module, either for building your own SIP stack from scratch, or developing your own tools for parsing & manipulating SIP.

The following example shows how to parse a SIP message, create a copy of it and by registering functions, some headers are manipulated at the time the SIP message is built.

  // (1)
final String rawMessage = new StringBuilder("BYE sip:bob@siplib.io:5060 SIP/2.0\r\n")
.append("Via: SIP/2.0/UDP 192.168.0.100:5060;rport;branch=z9hG4bK-28976-1-7\r\n")
.append("From: alice <sip:alice@aboutsip.com>;tag=28976SIPpTag001\r\n")
.append("To: bob <sip:bob@siplib.io>;tag=28972SIPpTag011\r\n")
.append("Call-ID: 1-28976@127.0.1.1\r\n")
.append("CSeq: 2 BYE\r\n")
.append("Contact: sip:alice@192.168.0.100\r\n")
.append("Max-Forwards: 70\r\n")
.append("Drop-Me: Drop this header on proxy\r\n")
.append("Subject: Example BYE Message\r\n")
.append("Content-Length: 0\r\n")
.append("\r\n").toString();

// (2)
final SipMessage bye = SipMessage.frame(rawMessage).toRequest();

// (3)
final SipMessage proxyBye = bye.copy()
.onRequestURI(uri -> uri.copy().withHost("sipstack.io").build())
.withHeader(SipHeader.create("X-SIP-Lib-Version", "2.x"))
.onHeader(header -> {
if (header.isSubjectHeader()) {
// change
return header.copy().withValue("Example of Proxied BYE Message").build();
} else if (header.is("Drop-Me")) {
// drop
return null;
}
// keep
return header;
})
.withTopMostRecordRouteHeader(RecordRouteHeader.withHost("62.63.64.65")
.withTransportTCP()
.build())
.withTopMostViaHeader(ViaHeader.withHost("62.63.64.65")
.withBranch().withTransportTCP().build())
.onViaHeader((index, via) -> via.withReceived("54.55.56.57"))
.build();

System.out.println(bye);
System.out.println(proxyBye);

  1. In this example we are creating a SIP message "manually" but of course, in a real-world application you typically would read bytes off of a network stream or perhaps read a set of SIP messages from a file in case you are building a tool of some sort. However, this is just an example so therefore we are doing it the hard way...
  2. Every object in siplib has a frame-method, which will attempt to frame the raw content into that object. This is true for SIP messages, SIP headers, SIP URIs etc. All frame-methods are overloaded and accept Strings, Buffers and byte-arrays.
  3. One very common SIP application is to act as a SIP Proxy, which accepts an incoming message, finds the next hop and forwards the message there. When doing so, the proxy application may add some new headers, drop others, add a new top-most Via-header and manipulate the previous top Via etc. Since everything in siplib is immutable, a copy must be created, which returns a builder that allows you to perform the necessasry operations on the message before finally contstructing it through the build method.

The two resulting SIP messages are shown below, where the first one is the original BYE and the second one is the "proxy BYE". Note how the request URI on line 1 has changed from host 'siplib.io' to 'sipstack.io' due to the lambda expression registered with the onRequestURI method. In fact, this is the preferred way to manipulate any SIP message and the philopshy behind that is further discussed in the docs section. You'll also notice that a similar function was registered for non-system headers through the onHeader method as well as for Via-headers through the onViaHeader

BYE sip:bob@siplib.io:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.100:5060;rport;branch=z9hG4bK-28976-1-7
From: alice <sip:alice@aboutsip.com>;tag=28976SIPpTag001
To: bob <sip:bob@siplib.io>;tag=28972SIPpTag011
Call-ID: 1-28976@127.0.1.1
CSeq: 2 BYE
Contact: sip:alice@192.168.0.100
Max-Forwards: 70
Drop-Me: Drop this header on proxy
Subject: Example BYE Message
Content-Length: 0

BYE sip:bob@sipstack.io:5060 SIP/2.0
Via: SIP/2.0/TCP 62.63.64.65;branch=z9hG4bK-a2369a9d-840a-4634-a397-8c99dfffd9ba
Via: SIP/2.0/UDP 192.168.0.100:5060;rport;branch=z9hG4bK-28976-1-7;received=54.55.56.57
From: alice <sip:alice@aboutsip.com>;tag=28976SIPpTag001
To: bob <sip:bob@siplib.io>;tag=28972SIPpTag011
Call-ID: 1-28976@127.0.1.1
CSeq: 2 BYE
Contact: sip:alice@192.168.0.100
Max-Forwards: 70
Subject: Example of Proxied BYE Message
X-SIP-Lib-Version: 2.x
Record-Route: <sip:62.63.64.65;transport=tcp>
Content-Length: 0

Head over to the Get Started guide, which will take you through how to setup your project for using siplib.io.