Transport Interface Design |
This document contains the design of the new Transport Interface that will be deployed in OpenSIPS 2.1.
The current transport protocols (UDP, TCP, TLS, etc.) are embedded directly in the OpenSIPS core. This makes the management of these protocols in script more difficult and also complicates the addition of new ones (such as WebSockets).
In order to simplify this, we designed a new Transport Interface that aims to provide a new transport layer in OpenSIPS's core. This interface will separate the network level transport protocols (such as TCP and UDP) from higher level, SIP aware, protocols (such as TLS, WebSocket, SCTP). This clear separation will facilitate the addition of higher level protocols while efficiently reusing the lower network level protocols implementations.
The architecture of the new Transport Interface is presented in the picture below.
![]() |
The picture consists of three layers, from top down:
The last two points above will represent a separation of the current TCP/UDP implementations and will suffer major changes.
In order to interact between the three layers, the Transport Interface will provide three different APIs: Application(app
), Transport(trans
) and Network(net
).
app
)// looks for the transport protocol that knows how to handle the proto and calls the corresponding add_listener() function int add_listener(char* host, int proto, int port); // used to tune connection attributes int dst_fcntl(int id, union sockaddr_union* to, int attr, void *value); // called by the transport protocol when a whole message was received int recv_msg(char* buf, unsigned int len, struct receive_info* rcv_info); // used to send a buffer over the network int send_msg(struct socket_info *send_socket, int proto, \ union sockaddr_union* to, int id, char* buf, int len);
trans
)Each type of transport has to implement this structure
struct trans_proto { // the id of the protocol int proto; // the name of the protocol: UDP, SCTP. Used for detecting the outgoing/incoming socket char *name; // the default port for the protocol int default_port; // function called when the module is loaded int (*proto_init)(void); // function called to destroy the data initialized at startup void (*proto_destroy)(void); // adds a new listener read by the parser. The port might be missing, and the default_port is used further int (*add_listener)(char* host, int port); // binds the listener and returns a file descriptor (used by the WebSocket library) int (*bind)(char *host, int port); // connects to a different peer int (*connect)(union sockaddr_union* to); // initializes a new connection int (*conn_init)(struct connection *conn, void *ctx); // reads the data received on the connection int (*recv)(struct connection *conn, void *ctx); // used to send a buffer over the network int (*send)(struct connection *conn, char* buf, int len); }
net
)// binds the interface and adds the socket to the listening sockets int add_listener(char* host, int proto, int port); // used to return a listener struct socket_info* find_listener(union sockaddr_union* to, int proto); struct net_proto { // initializes the structures int (*init_tcp)(void); // initializes the listeners int (*init_listeners)(void); // destroys the TCP data void (*destroy_udp)(void); // returns the connection identified by either the id or the destination to struct connection* (*conn_get)(int id, union sockaddr_union* to); // used to tune connection attributes int (*conn_fcntl)(struct connection *conn, int attr, void *value); }
// initializes the TCP structures int init_tcp(void); // initializes the TCP listeners int init_tcp_listeners(void); // destroys the TCP data void destroy_tcp(void); // returns the connection identified by either the id or the destination to struct connection* conn_get(int id, union sockaddr_union* to); // used to tune connection attributes int conn_fcntl(struct connection *conn, int attr, void *value);
// initializes the UDP structures int init_udp(void); // initializes the UDP listeners int init_udp_listeners(void); // destroys the UDP data void destroy_udp(void);
The following diagrams represent the execution flows for the TCP network protocol.
The following scenario represents the state machine executed when a message is received.
![]() |
The next diagram represents the state machine executed when a message is sent by the OpenSIPS core or modules.
![]() |