The Routing Engine

In a previous section we discussed how routing part of a config file gets translated into binary representation. In this section, we will discuss how the binary representation is used during message processing.

Upon a SIP message receipt, the server performs some basic sanity checks and converts the message into sip_msg structure. After that the Routing Engine will start processing the message.

The routing engine can be found in file action.c.

The main function is run_actions. The function accepts two parameters. The first parameter is list of actions to be processed (Remember, the config file gets translated into array of linked lists. Each linked list in the array represents one "route" part of the config file). The second parameter is sip_msg structure representing the message to be processed.

Upon a receipt of a request, the linked list representing the main route part will be processed so the first parameter will be rlist[0]. (The linked list of main route part is always at index 0).

The function will then sequentially call do_action function for each element of the linked list. Return value of the function is important. If the function returns 0, processing of the list will be stopped. By returning 0 a command can indicate that processing of the message should be stopped and the message will be dropped.

Modules may export so-called on_break handlers. on_break handler is a function, that will be called when processing of the linked-list is interrupted (ret == 0). All such handlers will be called when processing of the linked-list is finished and ret == 0.

do_action Function

do_action function is core of the routing engine. There is a big switch statement. Each case of the statements is one command handled by the server core itself.

The following commands are handled by the SER core itself: drop, forward, send, log, append_branch, len_gt, setflag, resetflag, isflagset, error, route, exec, revert_uri, set_host, set_hostport, set_user, set_userpass, set_port, set_uri, prefix, strip, if, module.

Each of the commands is represented by a case statement in the switch. (For example, if you are interested in implementation of drop command, look at "case DROP_T:" statement in the function.

The respective commands will be described now.