📄 serdev.sgml
字号:
<!-- $Id: serdev.sgml,v 1.19 2004/08/24 08:45:12 janakj Exp $ --><!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook V4.2//EN"><book label="serdev" id="serdev" lang="EN"><?dbhtml filename="index.html"> <title>SIP Express Router v0.8.8 - Developer's Guide</title> <bookinfo> <authorgroup> <author> <firstname>Jan</firstname> <surname>Janak</surname> <email>J.Janak@sh.cvut.cz</email> </author> <author> <firstname>Jiri</firstname> <surname>Kuthan</surname> <email>jiri@iptel.org</email> </author> <author> <firstname>Bogdan</firstname> <surname>Iancu</surname> <email>Bogdan.Iancu@fokus.fraunhofer.de</email> </author> </authorgroup> <copyright> <year>2001</year> <year>2002</year> <holder>FhG Fokus</holder> </copyright> <legalnotice> <para> This documentation is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. </para> <para> This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. </para> <para> You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA </para> <para> For more details see the file COPYING in the source distribution of SER. </para> </legalnotice> <abstract> <para> The document describes the SIP Express Router internals and algorithms. It describes overall server architecture, request processing, configuration, memory management, interprocess locking, module interface and selected modules in detail. </para> <para> The document is intended mainly for module developers wishing to implement a new module for the server. Other people like developers of SIP related software or students might be interested too. </para> </abstract> </bookinfo> <toc></toc> <chapter id="server-startup"> <title>The Server Startup</title> <para> The <function moreinfo="none">main</function> function in file <filename moreinfo="none">main.c</filename> is the first function called upon server startup. It's purpose is to initialize the server and enter main loop. The server initialization will be described in the following sections. </para> <para> Particular initialization steps are described in order in which they appear in <function>main</function> function. </para> <section id="signal-installation"> <title>Installation Of New Signal Handlers</title> <para> The first step in the initialization process is the installation of new signal handlers. We need our own signal handlers to be able to do graceful shutdown, print server statistics and so on. There is only one signal handler function which is function <function moreinfo="none">sig_usr</function> in file <filename moreinfo="none">main.c</filename>. </para> <para> The following signals are handled by the function: SIGINT, SIGPIPE, SIGUSR1, SIGCHLD, SIGTERM, SIGHUP and SIGUSR2. </para> </section> <!-- signal-installation --> <section id="cmd-line-params"> <title>Processing Command Line Parameters</title> <para> <acronym>SER</acronym> utilizes the <function moreinfo="none">getopt </function>function to parse command line parameters. The function is extensively described in the man pages. </para> </section> <!-- cmd-line-params --> <section id="parser-init"> <title>Parser Initialization</title> <para> <acronym>SER</acronym> contains a fast 32-bit parser. The parser uses pre-calculated hash table that needs to be filled in upon startup. The initialization is done here, there are two functions that do the job. Function <function moreinfo="none">init_hfname_parser</function> initializes hash table in header field name parser and function <function moreinfo="none">init_digest_parser</function> initializes hash table in digest authentication parser. The parser's internals will be described later. </para> </section> <!-- parser-init --> <!-- <section id="hash-init"> <title>Hash Table Initialization</title> <para>TBD.</para> </section>--> <section id="malloc-init"> <title>Malloc Initialization</title> <para> To make <acronym>SER</acronym> even faster we decided to re-implement memory allocation routines. The new <function moreinfo="none">malloc</function> better fits our needs and speeds up the server a lot. The memory management subsystem needs to be initialized upon server startup. The initialization mainly creates internal data structures and allocates memory region to be partitioned. </para> <important> <para> The memory allocation code must be initialized <emphasis>BEFORE</emphasis> any of its function is called ! </para> </important> </section> <!-- malloc-init --> <section id="timer-init"> <title>Timer Initialization</title> <para> Various subsystems of the server must be called periodically regardless of the incoming requests. That's what timer is for. Function <function moreinfo="none">init_timer</function> initializes the timer subsystem. The function is called from <filename moreinfo="none">main.c</filename> and can be found in <filename moreinfo="none">timer.c</filename> The timer subsystem will be described later. </para> <warning> <para> Timer subsystem must be initialized before config file is parsed ! </para> </warning> </section> <!-- timer-init --> <section id="fifo-init"> <title><acronym>FIFO</acronym> Initialization</title> <para> <acronym>SER</acronym> has built-in support for <acronym>FIFO</acronym> control. It means that the running server can accept commands over a FIFO special file (a named pipe). Function <function moreinfo="none">register_core_fifo</function> initializes <acronym>FIFO</acronym> subsystem and registers basic commands, that are processed by the core itself. The function can be found in file <filename moreinfo="none">fifo_server.c</filename>. </para> <para> The <acronym>FIFO</acronym> server will be described in another chapter. </para> </section> <!-- fifo-init --> <section id="builtin-mod-reg"> <title>Built-in Module Initialization</title> <para> Modules can be either loaded dynamically at runtime or compiled in statically. When a module is loaded at runtime, it is registered <footnote id="regfoot"> <para> Module registration is a process when the core tries to find what functions and parameters are offered by the module. </para> </footnote> immediately with the core. When the module is compiled in statically, the registration<footnoteref linkend="regfoot"> must be performed during the server startup. Function <function moreinfo="none">register_builtin_modules</function> does the job. </para> </section> <!-- builtin-mod-reg --> <section id="ser-config"> <title>Server Configuration</title> <para> The server is configured through a configuration file. The configuration file is C-Shell like script which defines how incoming requests should be processed. The file cannot be interpreted directly because that would be very slow. Instead of that the file is translated into an internal binary representation. The process is called compilation and will be described in the following sections. </para> <note> <para> The following sections only describe how the internal binary representation is being constructed from the config file. The way how the binary representation is used upon a request arrival will be described later. </para> </note> <para>The compilation can be divided in several steps:</para> <section id="lex-analysis"> <title>Lexical Analysis</title> <para> Lexical analysis is process of converting the input (the configuration file in this case) into a stream of tokens. A token is a set of characters that 'belong' together. A program that can turn the input into stream of tokens is called scanner. For example, when scanner encounters a number in the config file, it will produce token NUMBER. </para> <para> There is no need to implement the scanner from scratch, it can be done automatically. There is a utility called flex. Flex accepts a configuration file and generates scanner according to the configuration file. The configuration file for flex consists of several lines - each line describing one token. The tokens are described using regular expressions. For more details, see flex manual page or info documentation. </para> <para> Flex input file for the <acronym>SER</acronym> config file is in file <filename moreinfo="none">cfg.lex</filename>. The file is processed by flex when the server is being compiled and the result is written in file <filename moreinfo="none">lex.yy.c</filename>. The output file contains the scanner implemented in the C language. </para> </section> <!-- lex-analysis --> <section id="syntax-analysis"> <title>Syntactical Analysis</title> <para> The second stage of configuration file processing is called syntactical analysis. Purpose of syntactical analysis is to check if the configuration file has been well formed, doesn't contain syntactical errors and perform various actions at various stages of the analysis. Program performing syntactical analysis is called parser. </para> <para> Structure of the configuration file is described using grammar. Grammar is a set of rules describing valid 'order' or 'combination' of tokens. If the file isn't conformable with it's grammar, it is syntactically invalid and cannot be further processed. In that case an error will be issued and the server will be aborted. </para> <para> There is a utility called yacc. Input of the utility is a file containing the grammar of the configuration file, in addition to the grammar, you can describe what action the parser should do at various stages of parsing. For example, you can instruct the parser to create a structure describing an <acronym>IP</acronym> address every time it finds an <acronym>IP</acronym> address in the configuration file and convert the address to its binary representation. </para> <para>For more information see yacc documentation.</para> <para> yacc creates the parser when the server is being compiled from the sources. Input file for yacc is <filename moreinfo="none">cfg.y</filename>. The file contains grammar of the config file along with actions that create the binary representation of the file. Yacc will write its result into file <filename moreinfo="none">cfg.tab.c</filename>. The file contains function <function moreinfo="none">yyparse</function> which will parse the whole configuration file and construct the binary representation. For more information about the bison input file syntax see bison documentation. </para> </section> <!-- syntax-analysis --> <section id="config-file-struct"> <title>Config File Structure</title> <para> The configuration file consist of three sections, each of the sections will be described separately. </para> <itemizedlist> <listitem> <para> <emphasis>Route Statement</emphasis> - The statement describes how incoming requests will be processed. When a request is received, commands in one or more <quote>route</quote> sections will be executed step by step. The config file must always contain one main <quote>route</quote> statement and may contain several additional <quote>route</quote> statements. Request processing always starts at the beginning of the main <quote>route</quote> statement. Additional <quote>route</quote> statements can be called from the main one or another additional <quote>route</quote> statements (It it similar to function calling). </para> </listitem> <listitem> <para> <emphasis>Assign Statement</emphasis> - There are many configuration variables across the server and this statement makes it possible to change their value. Generally it is a list of assignments, each assignment on a separate line. </para> </listitem> <listitem> <para> <emphasis>Module Statement</emphasis> - Additional functionality of the server is available through separate modules. Each module is a shared object that can be loaded at runtime. Modules can export functions, that can be called from the configuration file and variables, that can be configured from the config file. The module statement makes it possible to load modules and configure them. There are two commands in the statement - <function moreinfo="none">loadmodule</function> and <function moreinfo="none">modparam</function>. The first can load a module. The second one can configure module's internal variables. </para> </listitem> </itemizedlist> <para> In the following sections we will describe in detail how the three sections are being processed upon server startup. </para> <section id="route-stm"> <title>Route Statement</title> <para>The following grammar snippet describes how the route statement is constructed</para> <programlisting format="linespecific">route_stm = "route" "{" actions "}" { $$ = push($3, &rlist[DEFAULT_RT]); } actions = actions action { $$ = append_action($1, $2}; } | action { $$ = $1; }action = cmd SEMICOLON { $$ = $1; } | SEMICOLON { $$ = 0; }cmd = "forward" "(" host ")" { $$ = mk_action(FORWARD_T, STRING_ST, NUMBER_ST, $3, 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -