⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serdev.sgml

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 SGML
📖 第 1 页 / 共 5 页
字号:
    | ...</programlisting>		    <para>			A config file can contain one or more "route" statements. "route" statement without			number will be executed first and is called the main route statement. There can be			additional route statements identified by number, these additional route statements			can be called from the main route statement or another additional route statements.		    </para>		    <para>			Each route statement consists of a set of actions. Actions in the route statement are			executed step by step in the same order in which they appear in the config file. Actions in the 			route statement are delimited by semicolon.		    </para>		    <para>			Each action consists of one and only one command (cmd in the grammar). There are many types			of commands defined. We don't list all of them here because the list would be too long and all the			commands are processed in the same way. Therefore we show only one example (forward) and			interested readers might look in <filename moreinfo="none">cfg.y</filename> file for			full list of available commands.		    </para>		    <para>			Each rule in the grammar contains a section enclosed in curly braces. The section is the C code			snippet that will be executed every time the parser recognizes that rule in the config file.		    </para>		    <para>			For example, when the parser finds <function moreinfo="none">forward</function> command, 			<function moreinfo="none">mk_action</function> function (as specified in the			grammar snippet above) will be called. The function creates a new structure with 			<structfield>type</structfield> field set to FORWARD_T representing the command. Pointer 			to the structure will be returned as the return value of the rule.		    </para>		    <para>			The pointer propagates through <function moreinfo="none">action</function> rule to 			<function moreinfo="none">actions</function> rule. <function moreinfo="none">Actions</function> rule 			will create linked list of all commands. The linked list will be then inserted into  			<structfield>rlist</structfield> table.			(Function <function moreinfo="none">push</function> in rule <function moreinfo="none">route_stm</function>).			Each element of the table represents one <quote>route</quote> statement of the config file.		    </para>		    <para>			Each route statement of the configuration file will be represented by a linked list of all			actions in the statement. Pointers to all the lists will be stored in rlist array. Additional			route statements are identified by number. The number also serves as index to the array.		    </para>		    <para>			When the core is about to execute route statement with number n, it will look in the array			at position n. If the element at position n is not null then there is a linked list of			commands and the commands will be executed step by step.		    </para>		    <para>			Reply-Route statement is compiled in the same way. Main differences are:			<itemizedlist>			    <listitem>				<para>				    Reply-Route statement is executed when a <acronym>SIP</acronym> <emphasis>REPLY</emphasis> 				    comes (not ,<acronym>SIP</acronym> <emphasis>REQUEST</emphasis>).				</para>			    </listitem>			    <listitem>				<para>				    Only subset of commands is allowed in the reply-route statement.				    (See file <filename moreinfo="none">cfg.y</filename> for more details).				</para>			    </listitem>			    <listitem>				<para>Reply-route statement has it's own array of linked-lists.</para>			    </listitem>			</itemizedlist>		    </para>		    		</section> <!-- route-stm -->				<section id="assign-stm">		    <title>Assign Statement</title>		    <para>			The server contains many configuration variables. There is a section of the			config file in which the variables can be assigned new value. The section			is called The Assign Statement. The following grammar snippet describes how the section			is constructed (only one example will be shown):		    </para>		    <programlisting format="linespecific">assign_stm = "children" '=' NUMBER { children_no=$3; }	   | "children" '=' error  { yyerror("number expected"); } ...</programlisting>		    <para>			The number in the config file is assigned to <varname>children_no</varname> variable. 			The second statement will be executed if the parameter is not number or is in invalid 			format and will issue an error and abort the server.		    </para>		</section> <!-- assign-stm -->				<section id="module-stm">		    <title>Module Statement</title>		    <para>			The module statement allows module loading and configuration. There are two commands:		    </para>		    <itemizedlist>			<listitem>			    <para>				<emphasis>loadmodule</emphasis> - Load the specified module in form of a shared object. 				The shared object will be loaded using <function moreinfo="none">dlopen</function>.			    </para>			</listitem>			<listitem>			    <para>				<emphasis>modparam</emphasis> - It is possible to configure a module using this 				command. The command accepts 3 parameters: 				<emphasis>module name</emphasis>, <emphasis>variable name</emphasis> 				and <emphasis>variable value</emphasis>.			    </para>			</listitem>		    </itemizedlist>		    <para>The following grammar snippet describes the module statement:</para>		    <programlisting format="linespecific">module_stm = "loadmodule" STRING {     DBG("loading module %s\n", $2);    if (load_module($2)!=0) {        yyerror("failed to load module");    }}	   | "loadmodule" error	 { yyerror("string expected");  }	   | "modparam" "(" STRING "," STRING "," STRING ")" 			{			    if (set_mod_param($3, $5, STR_PARAM, $7) != 0) {			        yyerror("Can't set module parameter");			    }			}	   | "modparam" "(" STRING "," STRING "," NUMBER ")" 			{			    if (set_mod_param($3, $5, INT_PARAM, (void*)$7) != 0) {			        yyerror("Can't set module parameter");			    }			}	   | MODPARAM error { yyerror("Invalid arguments"); }</programlisting>		    <para>			When the parser finds <function moreinfo="none">loadmodule</function> command, it will execute 			statement in curly braces.			The statement will call <function moreinfo="none">load_module</function> function.			The function will load the specified filename using <function moreinfo="none">dlopen</function>.			If <function moreinfo="none">dlopen</function> was successful, the server will look for			<structname>exports</structname> structure describing the module's interface and register the 			module. For more details see <link linkend="module-interface">module section</link>.		    </para>		    <para>			If the parser finds <function moreinfo="none">modparam</function> command, it will try to configure 			the specified variable in the			specified module. The module must be loaded using <function moreinfo="none">loadmodule</function>			before <function moreinfo="none">modparam</function> for the module can be used !			Function <function moreinfo="none">set_mod_param</function> will be called and will			configure the variable in the specified module.		    </para>		</section> <!-- module-stm -->	    </section> <!-- config-file-struct -->	</section> <!-- ser-config -->		<section id="iface-config">	    <title>Interface Configuration</title>	    <para>		The server will try to obtain list of all configured interfaces of the host it is running on. If it		fails the server tries to convert hostname to <acronym>IP</acronym> address and will use interface with 		the <acronym>IP</acronym> address only.	    </para>	    <para>		Function <function moreinfo="none">add_interfaces</function> will add all configured interfaces to the		array.	    </para>	    <para>		Try to convert all interface names to IP addresses, remove duplicates...	    </para>	</section> <!-- iface-config -->		<section id="daemon">	    <title>Turning into a Daemon</title>	    <para>		When configured so, <acronym>SER</acronym> becomes a daemon during startup. A process is called daemon		when it hasn't associated controlling terminal. See function 		<function moreinfo="none">daemonize</function> in file 		<filename moreinfo="none">main.c</filename> for more details.		The function does the following:	    </para>	    <itemizedlist>		<listitem>		    <para>			<emphasis>chroot</emphasis> is performed if necessary. That ensures that the server will have			access to a particular directory and its subdirectories only.		    </para>		</listitem>		<listitem>		    <para>			Server's working directory is changed if the new working directory was			specified (usually it is /).		    </para>		</listitem>		<listitem>		    <para>			If command line parameter -g was used, the server's group ID is changed			to that value.		    </para>		</listitem>		<listitem>		    <para>			If command line parameter -u was used, the server's user ID is changed			to that value.		    </para>		</listitem>		<listitem>		    <para>			Perform <emphasis>fork</emphasis>, let the parent process exit. This ensures that we 			are not a group leader.		    </para>		</listitem>		<listitem>		    <para>			Perform <emphasis>setsid</emphasis> to become a session leader and drop the controlling 			terminal.		    </para>		</listitem>		<listitem>		    <para>			Fork again to drop group leadership.		    </para>		</listitem>		<listitem>		    <para>Create a pid file.</para>		</listitem>		<listitem>		    <para>Close all opened file descriptors.</para>		</listitem>	    </itemizedlist>	</section> <!-- daemon -->		<section id="module-init">	    <title>Module Initialization</title>	    <para>		The whole config file was parsed, all modules were loaded already and can		be initialized now. A module can tell the core that it needs to be initialized		by exporting <function moreinfo="none">mod_init</function> function.		<function moreinfo="none">mod_init</function> function of all loaded modules		will be called now.	    </para>	</section> <!-- module-init -->	<section id="rt-list-fix">	    <title>Routing List Fixing</title>	    <para>		After the whole routing list was parsed, there might be still places that can be		further processed to speed-up the server. For example, several commands accept		regular expression as one of their parameters. The regular expression can be compiled		too and processing of compiled expression will be much faster.	    </para>	    <para>		Another example might be string as parameter of a function. For example if you call		<function moreinfo="none">append_hf("Server: SIP Express Router\r\n")</function> from the routing 		script, the function will 		append a new header field after the last one. In this case, the function needs to know length 		of the string parameter. It could call <function moreinfo="none">strlen</function> every time it is		called, but that is not a very good idea because <function moreinfo="none">strlen</function> would		be called every time a message is processed and that is not necessary.	    </para>	    <para>		Instead of that the length of the string parameter could be pre-calculated upon server startup, saved		and reused later. The processing of the request will be faster because 		<function moreinfo="none">append_hf</function> doesn't need		to call <function moreinfo="none">strlen</function> every time, I can just reuse the saved value.	    </para>	    <para>		This can be used also for string to int conversions, hostname lookups, expression evaluation and so on.	    </para>	    <para>		This process is called Routing List Fixing and will be done as one of last steps of the server startup.	    </para>	    <para>		Every loaded module can export one or more functions. Each such function can have associated a fixup		function, which should do fixing as described in this section. All such fixups of all loaded modules		will be called here. That makes it possible for module functions to fix their parameters too if necessary.	    </para>	</section> <!-- rt-list-fix -->	<section id="stat-init">	    <title>Statistics Initialization</title>	    <para>		If compiled-in, the core can produce some statistics about itself and traffic processed. The statistics		subsystem gets initialized here, see function <function moreinfo="none">init_stats</function>.	    </para>	</section> <!-- stat-init -->	<section id="socket-init">	    <title>Socket Initialization</title>	    <para>		UDP socket initialization depends on <varname>dont_fork</varname> variable. If this variable is set 		(only one process will		be processing incoming requests) and there are multiple listen interfaces, only the first one will be used. This		mode is mainly for debugging.	    </para>	    <para>		If the variable is not set, then sockets for all configured interfaces will be created and initialized.		See function <function moreinfo="none">udp_init</function> in file		<filename moreinfo="none">udp_server.c</filename> for more details.	    </para>	</section> <!-- socke-init -->		<section id="forking">	    <title>Forking</title>	    <para>		The rest of the initialization process depends on value of <varname>dont_fork</varname> variable. 		<varname>dont_fork</varname> is a global variable defined in <filename moreinfo="none">main.c</filename>.		We will describe both variants separately.	    </para>	    <section id="dont-fork-set">		<title><varname>dont_fork</varname> variable is set (not zero)</title>		<para>		    If <varname>dont_fork</varname> variable is set, the server will be operating in special mode. 		    There will be only one process processing incoming requests. This is very slow and was intended mainly 		    for debugging purposes. The main process will be processing all incoming requests itself.		</para>		<para>		    The server still needs additional children:		</para>		<itemizedlist>		    <listitem>			<para>			    One child is for the timer subsystem, the child will be processing timers independently of 			    the main process.			</para>		    </listitem>		    <listitem>			<para>			    <acronym>FIFO</acronym> server will spawn another child if enabled. The child will be 			    processing all commands coming through the fifo interface.			</para>		    </listitem>		    <listitem>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -