SCTP in Go
SCTP in Go
SCTP in Go
Olivier Van Acker
Department of Computer Science and Information Systems
Birkbeck University of London
London, United Kingdom
Email: [email protected]
Abstract—This paper describes a successful attempt to com- browser this year implementing the WebRTC standard. Go as
bine two relatively new technologies: Stream Control Trans- a language is very new and it is too early to say what impact
mission Protocol (SCTP) and the programming language Go, it will have. It does however receive a lot of media attention
achieved by extending the existing Go network library with
SCTP. since it is developed by Google. It is also growing in popularity
SCTP is a reliable, message-oriented transport layer protocol, because of its ease of use as a concurrent system language [1].
similar to TCP and UDP. It offers sequenced delivery of messages
over multiple streams, network fault tolerance via multihoming
support, resistance against flooding and masquerade attacks B. Outline
and congestion avoidance procedures. It has improvements over
wider-established network technologies and is gradually gaining Section II presents an overview of Go and SCTP, followed
traction in the telecom and Internet industries. by (section III) a description of how the TCP socket API
Go is an open source, concurrent, statically typed, compiled is integrated in the Go networking library. This is a starting
and garbage-collected language, developed by Google Inc. Go’s
main design goals are simplicity and ease of use and it has a
point for the design of an SCTP extension to the network
syntax broadly similar to C. Go has good support for networked library in Go, described in section IV. Section V explains
and multicore computing and as a system language is often used the implementation. Section VI analysis the results and VII
for networked applications, however it doesn’t yet support SCTP. concludes.
By combining SCTP and Go, software engineers can exploit the
advantages of both technologies. The implementation of SCTP
extending the Go network library was done on FreeBSD and II. T ECHNOLOGY OVERVIEW
Mac OS X - the two operating systems that contain the most up
to date implementation of the SCTP specification. In this section I will give an overview of the main features
Index Terms—Stream Control Transmission Protocol (SCTP); of SCTP and Go.
Transmission Control Protocol (TCP); Go; Networking;
A. SCTP
I. I NTRODUCTION
SCTP was initially developed in response to the demands
This paper will look into combining two relatively new
of the telecoms industry, which was not satisfied with the
technologies: a network protocol called SCTP and the pro-
reliability and performance of TCP [10, p. 15]. During the
gramming language Go. Both technologies claim to offer
design phase the decision was made to make SCTP a less
improvements over existing technologies: SCTP does away
telephony-centric IP protocol [10, p. 16] so that it could also
with the limitations of the widely used TCP protocol [8]; and
be used for more generic data transport purposes.
Go was designed with simplicity and minimized programmer
effort in mind, thereby preventing a forest of features getting 1) Comparison with TCP: It is fruitful to compare TCP
in the way of program design: Less is exponentially more [6]. and SCTP, as TCP is the most widely-used protocol [5] and
The current version of the Go network library does not support SCTP is very similar to it:
the SCTP protocol and this paper examines how easy it is to 2) Multihoming: A host is said to be multihomed if it has
extend the Go network library with this protocol. The work in multiple IP addresses which can be associated with one or
this paper is based on the dissertation submitted for an MSc more physical interfaces connected to the same or different
in Computer Science at Birkbeck University in London and is networks[2]. TCP can only bind to one network address at
available as an open source project. each end of the connection. In the event of a network failure
there is no way to stay connected and send the data over
another physical path without setting up a new connection.
A. Relevance SCTP natively supports multihoming at the transport layer.
After ten years SCTP as a technology is becoming more This makes it possible to connect and transfer data to and
and more relevant. One notable implementation is the use of from multihomed hosts, so that when one network path fails,
SCTP as a data channel in the Web Real-Time Communication the connection seamlessly fails over using the remaining paths.
(WebRTC) standard [11], a HTML 5 extension to enable real And together with concurrent multipath transfer (CMT) [4] it
time video and audio communication in browsers. Google inc. is possible to increase data throughput by transferring data
and the Mozilla Foundation are each planning to release a simultaneously over multiple links.
2
3) In-built message boundaries: In TCP there are no mark- Figure 2: Head of line blocking
ers to indicate the start or end of a specific piece of data (a 9 user messages ready to be send
user message). All data sent over the socket is converted into
a byte stream and an application must add its own mechanism 9 8 7 6 5 4 3 2 1
SCTP association
in order and becuase one message did not arrive. Socket API
6) Associations: A connection between a SCTP server and TCP Transport protocol TCP
UDP UDP transport layer
client is called an association. An association gets initiated SCTP SCTP
8) Socket API: Figure 4 is an overview of two applications Figure 6: Ancillary data embedded in sendmsg() data structure
communicating over an IP network using a transport protocol
msghdr
(TCP, UDP or SCTP). The software engineer writing the client
SCTP_SNDINFO
and server in the application layer only has to know about msg_name sockaddr
snd_sid
the function calls exposing the functionality in the transport msg_iov iovec
snd_flags
layer. This collection of functions is called the socket API. A
msg_control snd_ppid
socket is an endpoint for networked communication; multiple
processes can open sockets via the API and data written into snd_context
cmsghdr
one socket can be read from another. The socket API consist cmsg_level sctp_sndinfo snd_assoc_id
&
of functions which can open and close the socket, send data cmsg_type
over it and set the behavior of a socket using ’socket options’.
An example of such behavior is the enabling or disabling of flags
data buffering before sending to reduce the number of packets
to sent over the network and therefore improve efficiency
(Nagle’s algorithm).
Table I: Ancillary data mappings
Figure 5: TCP and SCTP socket API sid stream identifier
ssn stream sequence number
TCP SCTP ppid identifier set by peer
aid association id
Server Client Server Client
socket() socket()
The server gets created with the Listen() method and returns
an object which implements the Listener interface. On line 9
A. The network library a byte array buffer gets created for the received data. The
following for loop (10 - 17) will continuously wait to accept
Go provides a portable interface for network I/O. Basic an incoming connection (11), check for errors after connect,
interaction is provided by the Dial, Listen, ListenPacket and read from it (15) and convert the byte array to a string before
Accept functions which return implementations of the Conn, printing it (16).
PacketConn and Listener interfaces. The Listen function is
for byte stream data connections and the ListenPacket is for B. Under the hood
data transfer which includes messages boundaries, like UDP Go’s network communication library uses the same socket
or Unix domain sockets. These functions simplify the access API as any C program. In this section I will examine what
to the socket API, but if needed the application developer can happens when a network connection is set up and which socket
still access the socket API in more detail. API calls are made at what point. The example uses TCP. To
Here is an example of a typical TCP client and server illustrate how Go accesses the socket API I will take the TCP
application. The client sends a single message and the server client described in the previous section as an example and
waits to receive a message, prints it out after receiving and show how it interacts with the kernel by opening a connection.
starts listening again. First a simple client: Socket and Connect: For a TCP client to create a connection
and send some data the following system calls need to be made
in this order:
1 package main
2 import " n e t " 1) resolve IP address
3 2) socket()
4 func main ( ) {
5 conn , e r r : = n e t . D i a l ( " t c p " , " l o c a l h o s t :1234 " ) 3) setsockopt() (optional)
6 i f err != n i l { 4) connect()
7 return
8 } In Go all this is wrapped in the net.Dial() call.
9 defer conn . Close ( ) Figure 8 shows a sequence diagram of method calls after a
10 conn . W r i t e ( [ ] byte ( " H e l l o w o r l d ! " ) )
11 } client calls Dial(). First the hostname:port gets parsed and re-
solved to an IP address (1.1)2 . Net.dialAddr() (1.3) determines
the transport protocol type and calls the relevant method,
The function main() is the entry point of the program.
net.DialTCP() in this case (1.3.1). Next net.internetSocket()
The first step the client performs is ’dialing’ a server with
gets called which internally calls socket() in the syscall pack-
the TCP protocol (line 5). The Dial() function returns a
age. Syscall.socket() is an auto-generated method based on C
connection which is an implementation of the Conn interface.
header files which describe the socket API.
After checking for errors (6-8) the defer keyword before the
Every network protocol in Go has its own connection type.
connection close command indicates the connection can be
As you can see in figure 8 the generic Dial() method eventually
finished as soon as it is no longer needed. In this case it
reaches the specific DialTCP() method which returns a TCP-
happens immediately after the write so it does not make much
specific connection type. This type gets cast to the more
sense to defer it, but in larger programs with multiple exit
generic Conn type which can be used in the client application.
points you only need a single (deferred) close statement, which
If TCP-specific functionality is needed the Conn type can be
makes it easier to understand and maintain the program.
recast to a TCPConn which then makes it possible to access
Next the server: TCP-specific functionality.
2 There are more method calls behind this but they are not relevant for this
1 http://golang.org/doc/effective_go.html example
6
bind()
package main
import (
net.Dail()
" net "
listen() socket() " strconv "
)
close() close()
In this program ListenSCTP returns a SCTP connection
type. This type implements Conn and PacketConn interface
3 System call name/number master file: and has the ReadFromSCTP method added to it. The println()
http://fxr.watson.org/fxr/source/kern/syscalls.master functions prints the stream id and the user message.
7
package main
A. Server import (
" net "
For a server to be able to set up a SCTP association it " strconv "
)
needs to create a socket, bind to it, optionally set some socket
options and start listening to it. A typical server will access func main ( ) {
addr , _ : = n e t . ResolveSCTPAddr ( " s c t p " , " l o c a l h o s t
the socket API in the following sequence: :4242 " )
1) socket() conn , _ : = n e t . ListenSCTP ( " s c t p " , addr )
defer conn . Close ( )
2) bind() for {
3) listen() message : = make ( [ ] byte , 1024)
_ , _ , stream , _ : = conn . ReadFromSCTP ( message )
4) recvmsg() p r i n t l n ( " stream " + s t r c o n v . I t o a ( i n t ( stream ) )
+ " : " + s t r i n g ( message ) )
The socket(), bind() and listen() functions will be wrapped }
into a Listen() method which returns a connection type. }
There are three variations: net.Listen(), net.ListenPacket()
and net.ListenSCTP(). The Go network library provides the In this program ListenSCTP() returns a SCTP connection
net.ListenPacket() method for packet-oriented networking like type. This type implements the Conn and PacketConn inter-
UDP, and net.Listen() for stream-oriented networking like faces and adds the ReadFromSCTP() method.
TCP. SCTP which is packet-oriented, can also make use
of the net.ListenPacket() method. ListenPacket() returns an
B. Client
implementation of the PacketConn interface which can be used
to read and write messages (recvmsg()). A simple SCTP echo In Go a client connection sets itself up with a call to the
server using the PacketConn interface might look like this: Dial() method. The Dial() method returns the generic Conn
interface. Every network protocol in Go has its own Dial()
method which returns a protocol-specific connection type. In
package main
import " n e t " the case of SCTP this is the PacketConn type which has
underneath it a specific SCTP connection type (SCTPConn).
func main ( ) { A simple SCTP client sending a single message would look
conn , _ : = n e t . L i s t e n P a c k e t ( " s c t p " , "
l o c a l h o s t :4242 " ) like this:
defer conn . Close ( )
message : = make ( [ ] byte , 1024)
conn . ReadFrom ( message ) package main
p r i n t ( s t r i n g ( message ) ) import " n e t "
}
func main ( ) {
addr , _ : = n e t . ResolveSCTPAddr ( " s c t p " , " l o c a l h o s t
:4242 " )
After the the main entry point a connection object is created conn , _ : = n e t . DialSCTP ( " s c t p " , n i l , addr )
via the ListenPacket() method. The parameters of this method defer conn . Close ( )
message : = [ ] byte ( " paard " )
indicate that the connection should use the SCTP protocol conn . WriteTo ( message , addr )
and listen on localhost port 4242. The next line defers the }
closing of the connection when it is not needed anymore. After
creating a byte array buffer to store incoming data a message is The DialSCTP() method creates the socket and sets default
read from the connection. The ReadFrom() method will block socket options. Sending the message via WriteTo() will im-
until a message is received. Finally the message is printed and plicitly set up the connection.
the program ends. Send SCTP-specific information: To be able to set SCTP-
Receive SCTP-specific information: To access SCTP- specific send information such as stream id or association id
specific functionality, such as which stream the message has via the SCTP Send Information Structure, the WriteToSCTP()
been sent on, or the association id, net.ListenSCTP() can be method can be used:
8
[8] R. Stewart. RFC 4960 - stream control transmission protocol, motivation. E. Message header structure and ancillary data
http://tools.ietf.org/html/rfc4960#section-1.1.
[9] Randall Stewart, Michael Tuexen, and Peter Lei. SCTP: what is it, and
how to use it? BSDCan 2008, 2008. s t r u c t msghdr {
[10] Randall R. Stewart and Qiaobing Xie. Stream Control Transmission void ∗msg_name ; /∗ o p t i o n a l address ∗ /
Protocol (SCTP): A Reference Guide. Addison Wesley, 1 edition, socklen_t msg_namelen ; /∗ s i z e o f address ∗ /
s t r u c t i o v e c ∗msg_iov ; /∗ s c a t t e r / gather array ∗/
October 2001. int msg_iovlen ; /∗ # elements i n msg_iov ∗ /
[11] Michael Tuexen, Salvatore Loreto, and Randell Jesup. RTCWeb void ∗ msg_control ; /∗ a n c i l l a r y data ∗ /
datagram connection. http://tools.ietf.org/html/draft-ietf-rtcweb-data- socklen_t msg_controllen ; /∗ a n c i l l a r y data b u f f e r l e n ∗ /
channel-00. int msg_flags ; /∗ f l a g s on message ∗ /
};
RemoteAddr ( ) Addr
SetDeadline ( t t i m e . Time ) e r r o r
SetReadDeadline ( t t i m e . Time ) e r r o r
S e t W r i t e D e a d l i n e ( t t i m e . Time ) e r r o r
}
B. PacketConn interface
type PacketConn i n t e r f a c e {
Close ( ) e r r o r
LocalAddr ( ) Addr
SetDeadline ( t t i m e . Time ) e r r o r
SetReadDeadline ( t t i m e . Time ) e r r o r
S e t W r i t e D e a d l i n e ( t t i m e . Time ) e r r o r
}
C. Listener interface
type L i s t e n e r i n t e r f a c e {
Accept ( ) ( c Conn , e r r e r r o r )
Close ( ) e r r o r
Addr ( ) Addr
}
1:
1.1:
1.1.1:
1.1.2: TCPAddr
1.2: Addr
1.3:
1.3.1:
1.3.1.1:
1.3.1.1.1:
1.3.1.1.2: int
1.3.1.2: netFD
1.3.2: TCPConn
1.4: Conn
11
1:
1.1:
1.1.1: resolve address
1.1.2:
1.1.2.1:
1.1.2.1.1:
1.1.2.1.1.1:
1.1.2.1.1.2:
1.1.2.1.2:
1.1.2.1.3:
1.1.2.1.4:
1.1.2.2:
1.1.3:
1.1.4: listen
1.1.5: