<html>
<head>
    <base href="https://wiki.asterisk.org/wiki">
            <link rel="stylesheet" href="/wiki/s/en/2176/25/9/_/styles/combined.css?spaceKey=AST&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://wiki.asterisk.org/wiki/display/AST/res_sip+design">res_sip design</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://wiki.asterisk.org/wiki/display/~mmichelson">Mark Michelson</a>
    </h4>
        <br/>
                         <h4>Changes (15)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h1. Public methods <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2. Service registration <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. {{int ast_sip_register_service(pjsip_module *module)}} <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >This is the opposite of ast_sip_register_service().  Unregistering a service means that PJSIP will no longer call into the module any more. This will likely occur when an Asterisk module is unloaded. <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h3. {{int ast_sip_send_request(XXX params to be determined)}} <br> <br>This function is a general-purpose way of sending a SIP request. Its typical use would be to send one-off messages such as an out of dialog SIP MESSAGE or an in-dialog SIP INFO. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. {{int ast_sip_register_authenticator(struct ast_sip_authenticator *auth)}} <br> <br>This allows for a module to register itself as a SIP authenticator. An authenticator has three main purposes: <br></td></tr>
            <tr><td class="diff-changed-lines" >1) Determining if authentication should be <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">done</span> <span class="diff-added-words"style="background-color: #dfd;">performed</span> on an incoming request <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">2) Challenging a request that requires authentication <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">2) Gathering credentials necessary for issuing an authentication challenge <br></td></tr>
            <tr><td class="diff-unchanged" >3) Authenticating a request that has credentials <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >Unregisters the currently registered authenticator. With no authenticator registered, requests cannot be authenticated. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h3. {{int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)}} <br> <br>This allows for a module to register itself as a SIP endpoint identifier. An endpoint identifier&#39;s purpose is to determine which endpoint a given SIP message has come from. <br> <br>Multiple endpoint identifiers may be registered so that if an endpoint cannot be identified by one identifier, it may be identified by another. <br> <br>Asterisk will provide two different endpoint identifiers by default. The first will identify an endpoint based on the user portion of the From URI. The second will identify an endpoint based on the IP address from which the request was received. <br> <br>h3. {{int ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)}} <br> <br>This stops an endpoint identifier from the being used. <br> <br>h2. Threadpool usage <br> <br>h3. {{struct ast_sip_work *ast_sip_create_work(void)}} <br> <br>This creates a new SIP work structure. What is SIP work? It&#39;s a means of grouping together SIP tasks. For instance, one might create a SIP work so that all tasks for a given SIP dialog will be grouped together. Grouping the work together ensures that the threadpool will distribute the tasks in such a way so that grouped work will execute sequentially. Executing grouped tasks sequentially means less contention for shared resources. <br> <br>h3. {{int ast_sip_push_task(struct ast_sip_work *work, int (*sip_task)(void *), void *task_data)}} <br> <br>This will push a task into the SIP threadpool. This uses the {{ast_sip_work}} provided to determine how to push the task. <br> <br>h2. Common SIP methods <br> <br>h3. {{int ast_sip_send_request(const char *method, const char *body, struct pjsip_dialog *dlg}} <br> <br>This function is a general-purpose way of sending a SIP request. Its typical use would be to send one-off messages such as an out of dialog SIP MESSAGE or an in-dialog SIP INFO. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. {{int ast_sip_requires_authentication(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata)}} <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >This calls into an authenticator in order to determine if the request in {{rdata}} from {{endpoint}} contains proper credentials as to be authenticated. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >h3. {{int <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">ast_sip_challenge_request(struct</span> <span class="diff-added-words"style="background-color: #dfd;">ast_sip_get_authentication_credentials(struct</span> sip_digest_challenge_data *challenge)}} <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">This is a method that can be called by an authenticator in order to send a digest authentication challenge. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">This calls into an authenticator in order to get credentials required for challenging a request. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h3. {{int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)}} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h3. {{int ast_sip_challenge_request(struct sip_digest_challenge_data *challenge)}} <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">This allows for a module to register itself as a SIP endpoint identifier. An endpoint identifier&#39;s purpose is to determine which endpoint a given SIP message has come from. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">This method will send a SIP 401 response with the supplied challenge. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Multiple endpoint identifiers may be registered so that if an endpoint cannot be identified by one identifier, it may be identified by another. <br> <br>Asterisk will provide two different endpoint identifiers by default. The first will identify an endpoint based on the user portion of the From URI. The second will identify an endpoint based on the IP address from which the request was received.    <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. {{struct ast_sip_endpoint *ast_sip_identify_endpoint(struct pjsip_rx_data *rdata)}} <br> <br>This will call into each of the registered endpoint identifiers until one returns a non-NULL endpoint. The endpoint identifiers must return an endpoint if one can be identified based on the data in {{rdata}}. <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h3. {{int ast_sip_push_task(XXX some sort of identifier xxx, int (*sip_task)(void *), void *task_data)}} <br> <br>This will push a task into the SIP threadpool. In addition to the task and its relevant data, an identifier is passed in. All related tasks should pass in the same identifier to ensure that they are handled sequentially. For instance, all tasks pertaining to a specific dialog should have the same identifier so that they execute in order. This will allow for queued tasks to require less (or possibly no) locking. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. {{int ast_sip_add_header(struct pjsip_tx_data *tdata, const char *name, const char *value)}} <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/forbidden.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>This page is a work in progress. Please refrain from making comments until this warning has been removed</td></tr></table></div>

<h1><a name="res_sipdesign-Overview"></a>Overview</h1>

<p>res_sip is the decadent dark chocolate core of the new SIP work in Asterisk 12. It is the cockpit of the SIP jet. As such, its contents are those upon which all other SIP modules (and potentially non-SIP modules) will rely. The following describes its design and its public APIs.</p>

<h1><a name="res_sipdesign-Makeup"></a>Makeup</h1>

<p>res_sip can be divided into four overall sections:</p>

<ul>
        <li>service registrar</li>
        <li>SIP threadpool operator</li>
        <li>provider of common SIP methods</li>
        <li>servicer of PJSIP endpoint (i.e. reads incoming SIP messages)</li>
</ul>


<h1><a name="res_sipdesign-Startupprocess"></a>Startup process</h1>

<p>On startup, res_sip will create a threadpool for SIP to use. The threadpool's specifics will be discussed on a separate page. The threadpool will be used for as much of SIP's operation as possible. After starting the threadpool, res_sip will create a PJSIP endpoint and then begin handling incoming requests from the endpoint.</p>

<h1><a name="res_sipdesign-Publicmethods"></a>Public methods</h1>

<h2><a name="res_sipdesign-Serviceregistration"></a>Service registration</h2>

<h3><a name="res_sipdesign-%7B%7Bintastsipregisterservice%28pjsipmodulemodule%29%7D%7D"></a><tt>int ast_sip_register_service(pjsip_module *module)</tt></h3>

<p>This is more-or-less a wrapper around pjsip_endpt_register_module() except that it also adds the module to a container. Registering a service makes it so that PJSIP will call into the service at appropriate times. For more information about PJSIP module callbacks, see the PJSIP documentation. Asterisk modules that call this function will likely do so at module load time. As such, it is important that amongst SIP modules, res_sip should load before others.</p>

<h3><a name="res_sipdesign-%7B%7Bvoidastsipunregisterservice%28pjsipmodulemodule%29%7D%7D"></a><tt>void ast_sip_unregister_service(pjsip_module *module)</tt></h3>

<p>This is the opposite of ast_sip_register_service().  Unregistering a service means that PJSIP will no longer call into the module any more. This will likely occur when an Asterisk module is unloaded.</p>

<h3><a name="res_sipdesign-%7B%7Bintastsipregisterauthenticator%28structastsipauthenticatorauth%29%7D%7D"></a><tt>int ast_sip_register_authenticator(struct ast_sip_authenticator *auth)</tt></h3>

<p>This allows for a module to register itself as a SIP authenticator. An authenticator has three main purposes:<br/>
1) Determining if authentication should be performed on an incoming request<br/>
2) Gathering credentials necessary for issuing an authentication challenge<br/>
3) Authenticating a request that has credentials</p>

<p>Asterisk will implement an authenticator by default. Asterisk's default authenticator module may be replaced with a custom one if an alternate authentication mechanism is desired.</p>

<h3><a name="res_sipdesign-%7B%7Bvoidastsipunregisterauthenticator%28structastsipauthenticatorauth%29%7D%7D"></a><tt>void ast_sip_unregister_authenticator(struct ast_sip_authenticator *auth)</tt></h3>

<p>Unregisters the currently registered authenticator. With no authenticator registered, requests cannot be authenticated.</p>

<h3><a name="res_sipdesign-%7B%7Bintastsipregisterendpointidentifier%28structastsipendpointidentifieridentifier%29%7D%7D"></a><tt>int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)</tt></h3>

<p>This allows for a module to register itself as a SIP endpoint identifier. An endpoint identifier's purpose is to determine which endpoint a given SIP message has come from.</p>

<p>Multiple endpoint identifiers may be registered so that if an endpoint cannot be identified by one identifier, it may be identified by another.</p>

<p>Asterisk will provide two different endpoint identifiers by default. The first will identify an endpoint based on the user portion of the From URI. The second will identify an endpoint based on the IP address from which the request was received.</p>

<h3><a name="res_sipdesign-%7B%7Bintastsipunregisterendpointidentifier%28structastsipendpointidentifieridentifier%29%7D%7D"></a><tt>int ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)</tt></h3>

<p>This stops an endpoint identifier from the being used.</p>

<h2><a name="res_sipdesign-Threadpoolusage"></a>Threadpool usage</h2>

<h3><a name="res_sipdesign-%7B%7Bstructastsipworkastsipcreatework%28void%29%7D%7D"></a><tt>struct ast_sip_work *ast_sip_create_work(void)</tt></h3>

<p>This creates a new SIP work structure. What is SIP work? It's a means of grouping together SIP tasks. For instance, one might create a SIP work so that all tasks for a given SIP dialog will be grouped together. Grouping the work together ensures that the threadpool will distribute the tasks in such a way so that grouped work will execute sequentially. Executing grouped tasks sequentially means less contention for shared resources.</p>

<h3><a name="res_sipdesign-%7B%7Bintastsippushtask%28structastsipworkwork%2Cint%28siptask%29%28void%29%2Cvoidtaskdata%29%7D%7D"></a><tt>int ast_sip_push_task(struct ast_sip_work *work, int (*sip_task)(void *), void *task_data)</tt></h3>

<p>This will push a task into the SIP threadpool. This uses the <tt>ast_sip_work</tt> provided to determine how to push the task.</p>

<h2><a name="res_sipdesign-CommonSIPmethods"></a>Common SIP methods</h2>

<h3><a name="res_sipdesign-%7B%7Bintastsipsendrequest%28constcharmethod%2Cconstcharbody%2Cstructpjsipdialogdlg%7D%7D"></a><tt>int ast_sip_send_request(const char *method, const char *body, struct pjsip_dialog *dlg</tt></h3>

<p>This function is a general-purpose way of sending a SIP request. Its typical use would be to send one-off messages such as an out of dialog SIP MESSAGE or an in-dialog SIP INFO.</p>

<h3><a name="res_sipdesign-%7B%7Bintastsiprequiresauthentication%28structastsipendpointendpoint%2Cstructpjsiprxdatardata%29%7D%7D"></a><tt>int ast_sip_requires_authentication(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata)</tt></h3>

<p>This calls into an authenticator in order to determine if the request in <tt>rdata</tt> from <tt>endpoint</tt> requires authentication.</p>

<h3><a name="res_sipdesign-%7B%7Bintastsipauthenticaterequest%28structastsipendpointendpoint%2Cstructpjsiprxdatardata%29%7D%7D"></a><tt>int ast_sip_authenticate_request(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata)</tt></h3>

<p>This calls into an authenticator in order to determine if the request in <tt>rdata</tt> from <tt>endpoint</tt> contains proper credentials as to be authenticated.</p>

<h3><a name="res_sipdesign-%7B%7Bintastsipgetauthenticationcredentials%28structsipdigestchallengedatachallenge%29%7D%7D"></a><tt>int ast_sip_get_authentication_credentials(struct sip_digest_challenge_data *challenge)</tt></h3>

<p>This calls into an authenticator in order to get credentials required for challenging a request.</p>

<h3><a name="res_sipdesign-%7B%7Bintastsipchallengerequest%28structsipdigestchallengedatachallenge%29%7D%7D"></a><tt>int ast_sip_challenge_request(struct sip_digest_challenge_data *challenge)</tt></h3>

<p>This method will send a SIP 401 response with the supplied challenge.</p>

<h3><a name="res_sipdesign-%7B%7Bstructastsipendpointastsipidentifyendpoint%28structpjsiprxdatardata%29%7D%7D"></a><tt>struct ast_sip_endpoint *ast_sip_identify_endpoint(struct pjsip_rx_data *rdata)</tt></h3>

<p>This will call into each of the registered endpoint identifiers until one returns a non-NULL endpoint. The endpoint identifiers must return an endpoint if one can be identified based on the data in <tt>rdata</tt>.</p>

<h3><a name="res_sipdesign-%7B%7Bintastsipaddheader%28structpjsiptxdatatdata%2Cconstcharname%2Cconstcharvalue%29%7D%7D"></a><tt>int ast_sip_add_header(struct pjsip_tx_data *tdata, const char *name, const char *value)</tt></h3>

<p>This is a generic method for adding a header to a SIP request or response. More specialized modules may offer more specialized functions to add specific headers in case it is easier to express the header some other form than a name-value pair.</p>

<h3><a name="res_sipdesign-%7B%7Bintastsipaddbody%28structpjsiptxdatatdata%2Cconstcharbody%29%7D%7D"></a><tt>int ast_sip_add_body(struct pjsip_tx_data *tdata, const char *body)</tt></h3>

<p>This is a generic method for adding a body to a SIP request or response. More specialized modules may offer more specialized functions to add a body of a specific form in case it is easier to express the body in some other way than a string.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;" class="grey">
                        <a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=AST">Stop watching space</a>
            <span style="padding: 0px 5px;">|</span>
                <a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action">Change email notification preferences</a>
</div>
        <a href="https://wiki.asterisk.org/wiki/display/AST/res_sip+design">View Online</a>
        |
        <a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=22085835&revisedVersion=5&originalVersion=4">View Changes</a>
                |
        <a href="https://wiki.asterisk.org/wiki/display/AST/res_sip+design?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>