[asterisk-scf-commits] asterisk-scf/release/sip.git branch "authexten" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Fri Jun 17 16:56:27 CDT 2011


branch "authexten" has been updated
       via  68f3e523c1a9ab857a1031926d7dff2760d26df1 (commit)
       via  842ac2916a9dacfa0151dd121763d94aba3f23b5 (commit)
       via  c44cbcab1add8308822053fda7ebb73a79cadb1b (commit)
       via  3405b3d255c963ba920e859580e1d48062dd241b (commit)
       via  f629cf1b575eb73348d837cd2864a7f76c1a4159 (commit)
       via  9b157bc4d9957ef74d6cf277035305ea2c39f0bb (commit)
       via  a41ade002c57ccdd90495a8c0d50ba40dd69e19d (commit)
       via  d85f529e42fa80a0a9f3309c34aab9d5b19fa1cc (commit)
       via  edef933ea00de1a54440827f7731e7732d06efeb (commit)
       via  f8f80a33da9ca89ee1c2d6f7e01a53eeddb723d5 (commit)
       via  700a00bcbae0ee7d6e04353b35007daedd87e2cf (commit)
       via  b4996480a53d71759531ca0ddd8c78fc2b3c96aa (commit)
       via  50741df4192403a029c07a9348983023de1d8a3e (commit)
       via  0e36a390c38355413afde6da286342f780a35a87 (commit)
       via  fb9f4f3a7b813ee52200427d9c544eccb439ea37 (commit)
       via  c81b0fc11568a4b86ab67f8fc9de678f1692c2b8 (commit)
       via  b78b8a44294837357cece3e68fbafb00b2344c20 (commit)
       via  129d4f1fa49096b11f99e553c2c1a8bb6f8041a4 (commit)
       via  635de237c3aef8713ab818ceda11faf81930477d (commit)
       via  eac4258e1eae1ddb66c102438c6e4336f773e04e (commit)
       via  366a988285e61b635662501351607e8f45659c16 (commit)
       via  13b6132b4f653ae22175e55c14a375cf0ecb2622 (commit)
       via  20239f35caeaca630680c7719c70808deeab42ca (commit)
       via  960d3916fcb553e42df35266060363a425972007 (commit)
       via  f233332d7f4039a7fb007a42c207eb988dd9c77e (commit)
       via  71753eef2f0662b2642b0f5beef628c07c891bba (commit)
       via  ccfb81d546c08b540f175a65fc905123f430f4fc (commit)
       via  4709f65485b46d0c5299d7e8877c1c7b58326444 (commit)
       via  6e45f7d7d7ec3e8be48c53e0b581a946171b1c59 (commit)
       via  5e0a6d5fd9e409306d77ec066506a8de6afa6be4 (commit)
       via  069e20776fc5e0d44dbe7d5e4963167d93e64d6a (commit)
       via  56969fd2d98b159e1695d77a689fb78ecbfb6ebf (commit)
       via  30f4658ce0ba340fd90667a5483714ada1e5097c (commit)
       via  98584e0f7b7db43e806c59053c5c3df397152521 (commit)
       via  c807bf56d40a56549bc37ea3a3e46d8f540821da (commit)
       via  7246f8002b621284be27c987248888c5f701b7de (commit)
       via  b04ec118712501b0512f7c231015dfba60d8d965 (commit)
       via  8eb9a6461494bff1489e01b5541b569e7ecef3bc (commit)
       via  40f2cf7feed6d313e0f59a3188906960ea0eb84c (commit)
       via  57d2734e77552204087bcddeb9fa183255a4d140 (commit)
       via  1580cf9ff932630cb695b181826263c7e293405c (commit)
       via  01e69f75a66763af70bca71aa0783e98169ffd72 (commit)
       via  33d9123112321a9aae36a9f021c1c00fb6b0c425 (commit)
       via  0c327d8e8c59536fda95b1e07f0c54f31b825fdd (commit)
       via  d64b6e6f37ba0048fd66948ae6caf0864af1b3a7 (commit)
       via  847e828ad8e207d2d16cbf6ade1b7004fb2426f2 (commit)
       via  5c696c9882975b9feb11c4ea2d535378e77bcd04 (commit)
       via  958eccbe685be31e05b8651dd7bc3a72a3d11c99 (commit)
       via  7d0b2a500d2e8867bc3fe8db177e2f968d97a849 (commit)
       via  a4f034dcfb22c527a701dc32eb24df15faf38622 (commit)
       via  a7f1600075e5990bbecef9f273bf8cb0af77f444 (commit)
       via  623654b3e60749219d9fa790649f6833200c708f (commit)
       via  d64aea41b53bc585a88fa155bffe6c02562f29af (commit)
       via  72aedeaee32c837c3978f8e91d35af258dd6c880 (commit)
       via  349e921f0cc58898d43db5330643fc3789b0e7bf (commit)
       via  e9d1aa434ba33120497c9dee97ef386f955753b3 (commit)
       via  080f90db10d408e73b4dc9e8eeea8f32c5c0fcb1 (commit)
       via  81752bfad6b946001b867f04ab47ed1a73203b54 (commit)
       via  9fee5b0a87b2ca58c6c4c4a9fd20dc4773217d2c (commit)
       via  9353dd8149dd64b463bd207a9be0bc5bd02e1b8f (commit)
       via  673f9e8d81c71018e60c6e7117348528c679ac72 (commit)
       via  576ef02976be38ad1d9ce56a1d1a78145386acec (commit)
       via  8ca653bd739b1b898d408fc439c12cfd85fa1f81 (commit)
       via  e1847341cfa58fa1881760591e1b15c89a3b3d98 (commit)
       via  31f82419f61f057124629513bc58b08b0cbf3c0f (commit)
       via  9efb966a80d43d8472f1844e1960f7c3c4b26fc3 (commit)
       via  19dcde2cc6fabcf7abcfcc41a6987169910c70ee (commit)
       via  0aa8e7cbb655426867811936cf679d2add799d33 (commit)
       via  c7611f180ddcaab977b7c2450d1c2af7f5c30d22 (commit)
       via  275aecd899a44502b0a4f76eab747691bd92af5f (commit)
       via  3f83eaaeae44fb9716be7e0932fb52b67dbfb759 (commit)
       via  78e5e7f41cc406ab6fd735cd3bc2684f2ededd38 (commit)
       via  851a92b67b53c0f75bc703da381c4371d7aa0c23 (commit)
       via  e67a41c2641c54ab24d231d2d7e12ad17825bda3 (commit)
       via  1178a5061d81b691a58ffc2ac79be859a5feeade (commit)
       via  2e022453c47afd990d1f27e4403e813a45060e84 (commit)
       via  9f7b96df9ee33cb9469d21446a7cdde44c3ccb7a (commit)
       via  369e38a8e535a447a56e913dd3da63d857bc1ab0 (commit)
       via  1f9e8d9ff5e1fa75e0cd9f6be7699efc400dc796 (commit)
       via  556bf54a532d466b1b77c5872d01de211386ef15 (commit)
       via  bfbb0f9d2ced1b1ec12b1cf4c6b57625451bc47c (commit)
       via  8dd3dc0e1a319ae29aa0cfd7eb67955d26d79241 (commit)
       via  b2c9c8642fbde0022dd790f0a7fc4ccaa58071b1 (commit)
       via  76872d653fe255eb38335206d55eee31ad94f0c6 (commit)
       via  ee47a2ef8ac50751307755c71010d5c4b91effcc (commit)
       via  f268b4a8686fa136d4b6a4894d7232a439cf0b6f (commit)
       via  b917d36d4d91e0069678882fa6785a6ff78ce677 (commit)
       via  d395576d5663b58be0b3ac74609e735b5fa858d5 (commit)
       via  13f04bb0a3bc4098b7cc9b1a5f394e2876376292 (commit)
       via  5620383d390adef3a55d7a81234f1e1a8ff03430 (commit)
       via  5077625e83930a58b416ecac15e4a5a4faddf206 (commit)
       via  c7e5b4344e2f6745eeae14f1d77b6606a32475f7 (commit)
       via  2e4c74f5339433707eec29646d525d90be864ecc (commit)
       via  fd891bdc0b102fa187af0d4f44c24b1ded09c590 (commit)
       via  de1c49f45105d4a62b9572f8bf4efbf8c718933c (commit)
       via  0791f44ddb97bced3ded5da19580ba16966e9f63 (commit)
       via  2d535b3c8813521ba060c544c80baabc2b452f76 (commit)
       via  4c8c74c547955dd93c9e15d2f5c188918517aeeb (commit)
       via  ca95f560a6c8ccf5b3ffd2bff26249b982ecedea (commit)
       via  307e2b902ca3b1466aff00951914feb31bdedfec (commit)
       via  0fafee70d034c4406eb11b37817b12a70b50304e (commit)
       via  1f886e1225940e228bec9a983cf4a7b844e69cb4 (commit)
       via  24244fa6392253ffe2ff6c60757435be1b26da20 (commit)
       via  2b68a207e8b733c5d32f7f3baa63ab743a4a4f82 (commit)
       via  872dc33703f403a63e896a8b778a1e43fa7bad09 (commit)
       via  929982dac23f77950f2b7ff18ec85b51a42de558 (commit)
       via  95c838e77ca99e63a13721981e2aa07867c4bea1 (commit)
       via  d7418a0d23a8a23431e859442c782501abfc0553 (commit)
       via  7a25b8073e1e0d2bb2391a3feafb61b6bdacb380 (commit)
       via  6ced932f19f094541afd5c7ef8b069ea83f26438 (commit)
       via  238e6bb3ddcb4d697e3ac5189c73e0683132ad5e (commit)
       via  04e2c162bc7f6cd6b9bceb74089d1a9a29148b59 (commit)
       via  0c1ba29dc6631ac5ce38a3d2629fe17afcd39627 (commit)
       via  df6502431fb6d495c88eb9a223820f063432bd7e (commit)
       via  6fa0d1a69f5290d1154951965017380dc4e61825 (commit)
       via  06ba07d7d56ed8447eeb188eb4bb5770a9c41adc (commit)
       via  a2ce7d678f3574f6f63691dacead5e2574ded080 (commit)
       via  413bb6369fb40c99a952305fa924dc087da7792c (commit)
       via  626ae7f220d8b0ad44820a5110eeceb61248d032 (commit)
       via  ab478a5684fed6d71a1169104ff9067a240b1e81 (commit)
       via  dd6f1be516148b8f328adf3f174c43fe949a1b61 (commit)
       via  0024d93bcf841b13eec471b2d3f726cdbe686978 (commit)
       via  db6b6404ec286000fcb921edfe080fc6c2cc1c9d (commit)
       via  148efc74ad128c054300d461fb29ae8e31392bed (commit)
       via  827fc662e122ea00689893d167e77a46adf47a15 (commit)
       via  dc0dbb97620670914e030aab47cf1e0f90915ef1 (commit)
       via  c5ed0db396867362132166c17aac2a74274bb48d (commit)
       via  891cedd06767489bf8e00b9c1b98318d9c09d3ef (commit)
       via  0f17de699ae1b4e8f7abdb69053405a30b4b7952 (commit)
       via  4c5178bacdf897e9717c93187b2bcb657f2e1871 (commit)
       via  d17c5711691e51a7a46e787da409c568e8dc6cfd (commit)
       via  e37d9494e7db63a6f9e0798020dc3de62533da91 (commit)
       via  72138cabee93955fb3d648ac78c1faea422e2733 (commit)
       via  01940e42606ff1b41b53778a2b5148021be8d80b (commit)
       via  053aefa444ff4d34070d67d6f45809005c9c7c57 (commit)
       via  8b96c2315423a29b508d1d32622b5fd28b386653 (commit)
       via  116744bd3cb957d26797c50bcc63e4c673ec49ad (commit)
       via  7560c60db1c62ab3b846eba93098d9e81f1be09d (commit)
       via  db9137c28c816f89efc2f9d69accd5e60cc7ec95 (commit)
       via  1cc1ec91224cb05370e8e996433ecb7b5f8201fe (commit)
       via  49098782accde3746af4857574c15ceac1ea7916 (commit)
       via  475da6c6e49647d883663e3b93e443c57f415169 (commit)
       via  0adc89a842ccb2893a472539fe89ffb2e032f41a (commit)
       via  f9be80d1e56708c2673f952d14a0a42b35cb891e (commit)
       via  c004843947a6e1724a08225c7791cb46eee01304 (commit)
      from  44db9747153ed1c73ff0d95cfc977ea5548403db (commit)

Summary of changes:
 CMakeLists.txt                           |   39 +-
 config/Sip.config                        |   82 ++
 config/SipConfigurator.py                |  178 ++++
 config/test_sip_state_replicator.conf    |    8 +
 local-slice/SipConfigurationIf.ice       |  569 ++++++++----
 local-slice/SipStateReplicationIf.ice    |   19 +-
 src/AuthManager.cpp                      |   15 +-
 src/AuthManager.h                        |   16 +-
 src/CMakeLists.txt                       |   58 +-
 src/PJSipLoggingModule.cpp               |    8 +-
 src/PJSipLoggingModule.h                 |    2 +
 src/PJSipManager.cpp                     |  100 ++-
 src/PJSipManager.h                       |  105 ++-
 src/PJSipModule.cpp                      |   14 +-
 src/PJSipModule.h                        |    3 +-
 src/PJSipSessionModule.cpp               | 1585 +++++++++++++++++++-----------
 src/PJSipSessionModule.h                 |  225 ++++-
 src/PJSipSessionModuleConstruction.cpp   |   25 +-
 src/SipConfiguration.cpp                 | 1525 ++++++++++++++++++++++++++++
 src/SipConfiguration.h                   |   48 +
 src/SipEndpoint.cpp                      |  123 ++-
 src/SipEndpoint.h                        |   66 +-
 src/SipEndpointFactory.cpp               |   24 +-
 src/SipEndpointFactory.h                 |   23 +-
 src/SipSession.cpp                       |  911 ++++++++++++-----
 src/SipSession.h                         |  116 ++-
 src/SipSessionManagerApp.cpp             |  195 +++--
 src/SipSessionManagerEndpointLocator.cpp |   22 +-
 src/SipSessionManagerEndpointLocator.h   |    9 +-
 src/SipSessionManagerEventPublisher.cpp  |   11 +-
 src/SipSessionManagerEventPublisher.h    |    2 +-
 src/SipStateReplicator.h                 |   47 +-
 src/SipStateReplicatorApp.cpp            |  153 +++-
 src/SipStateReplicatorListener.cpp       |   60 +-
 34 files changed, 5003 insertions(+), 1383 deletions(-)
 create mode 100644 config/Sip.config
 create mode 100755 config/SipConfigurator.py
 create mode 100644 src/SipConfiguration.cpp
 create mode 100644 src/SipConfiguration.h


- Log -----------------------------------------------------------------
commit 68f3e523c1a9ab857a1031926d7dff2760d26df1
Merge: 44db974 842ac29
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Jun 7 16:07:38 2011 -0500

    Merge branch 'master' into authexten
    
    Also adjusted based on review feedback.
    
    Conflicts:
    	src/CMakeLists.txt
    	src/PJSipManager.cpp
    	src/PJSipManager.h
    	src/PJSipSessionModule.cpp
    	src/SipSessionManagerApp.cpp

diff --cc src/AuthManager.cpp
index 6e0e688,0000000..f91994e
mode 100644,000000..100644
--- a/src/AuthManager.cpp
+++ b/src/AuthManager.cpp
@@@ -1,437 -1,0 +1,440 @@@
 +/*
 + * Asterisk SCF -- An open-source communications framework.
 + *
 + * Copyright (C) 2011, Digium, Inc.
 + *
 + * See http://www.asterisk.org for more information about
 + * the Asterisk SCF project. Please do not directly contact
 + * any of the maintainers of this project for assistance;
 + * the project provides a web site, mailing lists and IRC
 + * channels for your use.
 + *
 + * This program is free software, distributed under the terms of
 + * the GNU General Public License Version 2. See the LICENSE.txt file
 + * at the top of the source tree.
 + */
 +
 +#include <boost/thread.hpp>
 +
 +#include "AuthManager.h"
 +
 +using namespace AsteriskSCF::SIP::ExtensionPoint::V1;
 +using namespace AsteriskSCF::System::Hook::V1;
 +using namespace AsteriskSCF::System::Logging;
 +
 +namespace AsteriskSCF
 +{
 +
 +namespace SipSessionManager
 +{
 +
 +class AuthHookData
 +{
 +public:
 +    AuthHookData(int priority, const AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx &hook,
 +            const AsteriskSCF::SIP::ExtensionPoint::V1::RequestTypeSeq &types)
 +        : mPriority(priority), mHook(hook), mTypes(types) { }
 +
 +    bool operator< (const AuthHookData &rhs) const
 +    {
 +        return mPriority < rhs.mPriority;
 +    }
 +
 +    int mPriority;
 +    AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx mHook;
 +    AsteriskSCF::SIP::ExtensionPoint::V1::RequestTypeSeq mTypes;
 +};
 +
 +class AuthInstancePriv
 +{
 +public:
 +    AuthInstancePriv(pjsip_rx_data *rdata, const moduleHookVector &moduleHooks,
 +            RequestType type, pjsip_endpoint *endpoint, const Logger &logger)
-         : mEndpoint(endpoint), mPool(pjsip_endpt_create_pool(mEndpoint, "auth%p", 500, 256)),
++        : mEndpoint(endpoint),
++        mPool(pjsip_endpt_create_pool(mEndpoint, "auth%p", 500, 256)),
 +        mLogger(logger),
 +        fromTag(pj_strbuf(&rdata->msg_info.from->tag), pj_strlen(&rdata->msg_info.from->tag)),
 +        callId(pj_strbuf(&rdata->msg_info.cid->id), pj_strlen(&rdata->msg_info.cid->id))
 +    {
 +        if (moduleHooks.empty())
 +        {
 +            return;
 +        }
 +
 +        for (moduleHookVector::const_iterator iter = moduleHooks.begin(); iter != moduleHooks.end(); ++iter)
 +        {
 +            RequestTypeSeq types = (*iter)->mTypes;
 +            AuthHookPrx hook = (*iter)->mHook;
 +            for (RequestTypeSeq::iterator typeIter = types.begin(); typeIter != types.end(); ++typeIter)
 +            {
 +                if (*typeIter == type)
 +                {
 +                    hooks.push_back(hook);
 +                }
 +            }
 +        }
 +    }
 +
 +    ~AuthInstancePriv()
 +    {
 +        pjsip_endpt_release_pool(mEndpoint, mPool);
 +    }
 +
 +    void getURIParams(const pjsip_uri *uri, ParamDict &params)
 +    {
 +        pjsip_sip_uri *sipURI = (pjsip_sip_uri *) pjsip_uri_get_uri(uri);
 +    
 +        if (pj_strlen(&sipURI->user_param) != 0)
 +        {
 +            params.insert(std::make_pair("user",
 +                        std::string(pj_strbuf(&sipURI->user_param),
 +                            pj_strlen(&sipURI->user_param))));
 +        }
 +        if (pj_strlen(&sipURI->method_param) != 0)
 +        {
 +            params.insert(std::make_pair("method",
 +                        std::string(pj_strbuf(&sipURI->method_param),
 +                            pj_strlen(&sipURI->method_param))));
 +        }
 +        if (pj_strlen(&sipURI->transport_param) != 0)
 +        {
 +            params.insert(std::make_pair("transport",
 +                        std::string(pj_strbuf(&sipURI->transport_param),
 +                            pj_strlen(&sipURI->transport_param))));
 +        }
 +        if (sipURI->ttl_param != -1)
 +        {
 +            std::stringstream stream;
 +            stream << sipURI->ttl_param;
 +            params.insert(std::make_pair("ttl", stream.str()));
 +        }
 +        //lr has no value associated with it. It either is there or it is not there. It is
 +        //the redheaded stepchild of the SIP URI parameter world. I weep for it.
 +        if (sipURI->lr_param != 0)
 +        {
 +            params.insert(std::make_pair("lr", std::string()));
 +        }
 +    
 +        for (pjsip_param *iter = sipURI->other_param.next;
 +                iter != &sipURI->other_param; iter = iter->next)
 +        {
 +            std::string name(pj_strbuf(&iter->name), pj_strlen(&iter->name));
 +            std::string value(pj_strbuf(&iter->value), pj_strlen(&iter->value));
 +            params.insert(std::make_pair(name, value));
 +        }
 +    }
 +
 +    std::vector<AuthHookPrx> hooks;
 +    std::vector<pjsip_auth_srv *> authServers;
 +    pjsip_endpoint *mEndpoint;
 +    pj_pool_t *mPool;
 +    pj_timer_entry entry;
 +    Logger mLogger;
 +    std::string fromTag;
 +    std::string callId;
 +};
 +
 +AuthInstance::AuthInstance(pjsip_rx_data *rdata, const moduleHookVector &hooks,
 +        RequestType type, pjsip_endpoint *endpoint, const Logger &logger)
 +        : mImpl(new AuthInstancePriv(rdata, hooks, type, endpoint, logger)) { }
 +
 +std::vector<AuthHookPrx> AuthInstance::getHooks()
 +{
 +    return mImpl->hooks;
 +}
 +
- static pj_status_t lookup_cred(pj_pool_t *pool, const pj_str_t *realm,
-         const pj_str_t *acc_name, pjsip_cred_info *cred_info)
++static pj_status_t lookup_cred(pj_pool_t *, const pj_str_t *,
++        const pj_str_t *, pjsip_cred_info *)
 +{
 +    // Return non-success for now just so it doesn't seem like authentication is actually succeeding.
 +    return !PJ_SUCCESS;
 +}
 +
 +bool AuthInstance::authenticate(pjsip_rx_data *rdata)
 +{
 +    //For each server auth, we need to call pjsip_auth_srv_verify(), which will then
 +    //annoyingly call into the lookup function we created for pjsip. That's where the
 +    //real fun begins :(
 +    for (std::vector<pjsip_auth_srv *>::iterator iter = mImpl->authServers.begin();
 +            iter != mImpl->authServers.end(); ++iter)
 +    {
 +        int status_code;
 +        pj_status_t status = pjsip_auth_srv_verify(*iter, rdata, &status_code);
 +        switch (status)
 +        {
 +        case PJ_SUCCESS:
 +            return true;
 +        case PJSIP_EAUTHNOAUTH:
 +        case PJSIP_EAUTHACCNOTFOUND:
 +        case PJSIP_EAUTHACCDISABLED:
 +        case PJSIP_EAUTHINVALIDREALM:
 +        case PJSIP_EAUTHINVALIDDIGEST:
 +        default:
 +            mImpl->mLogger(Warning) << "Could not auth";
 +        }
 +    }
 +    return false;
 +}
 +
++static const int AuthTimeoutSeconds = 60;
++
 +void AuthInstance::scheduleAuthTimeout(int id)
 +{
-     const pj_time_val time = {60, 0};
++    const pj_time_val time = {AuthTimeoutSeconds, 0};
 +    pj_timer_entry_init(&mImpl->entry, id, this, sessionAuthTimeout);
 +    pjsip_endpt_schedule_timer(mImpl->mEndpoint, &mImpl->entry, &time);
 +}
 +
 +void AuthInstance::addDigests(pjsip_tx_data *tdata, const DigestChallengeSeq &digests)
 +{
 +    static char qop[] = "auth";
 +    pj_str_t pjqop = pj_str(qop);
 +    for (DigestChallengeSeq::const_iterator digest = digests.begin();
 +            digest != digests.end(); ++digest)
 +    {
 +        pjsip_auth_srv *authServer = PJ_POOL_ZALLOC_T(mImpl->mPool, pjsip_auth_srv);
 +        pj_str_t realm;
 +        pj_cstr(&realm, (*digest)->realm.c_str());
 +        pjsip_auth_srv_init(mImpl->mPool, authServer, &realm, lookup_cred, 0);
 +        pj_str_t nonce, opaque, *noncePtr = NULL, *opaquePtr = NULL;
 +        if (!(*digest)->opaque.empty())
 +        {
 +            pj_cstr(&opaque, (*digest)->opaque.front().c_str());
 +            opaquePtr = &opaque;
 +        }
 +
 +        class visitor : public DigestChallengeVisitor
 +        {
 +        public:
-             visitor(pj_str_t *nonce, pj_str_t **noncePtr) : mNonce(nonce), mNoncePtr(noncePtr) { }
++            visitor(pj_str_t *theNonce, pj_str_t **theNoncePtr) : mNonce(theNonce), mNoncePtr(theNoncePtr) { }
 +        private:
 +            void visitAKAv1(AKAv1DigestChallengePtr aka, Ice::Current &)
 +            {
 +                pj_cstr(mNonce, aka->nonce.c_str());
 +                *mNoncePtr = mNonce;
 +            }
 +            void visitAKAv2(AKAv2DigestChallengePtr aka, Ice::Current &)
 +            {
 +                pj_cstr(mNonce, aka->nonce.c_str());
 +                *mNoncePtr = mNonce;
 +            }
 +
 +            pj_str_t *mNonce;
 +            pj_str_t **mNoncePtr;
 +        };
 +
 +        DigestChallengeVisitorPtr v = new visitor(&nonce, &noncePtr);
 +        (*digest)->visit(v);
 +
 +        pjsip_auth_srv_challenge(authServer, &pjqop, noncePtr, opaquePtr, PJ_FALSE, tdata);
 +        mImpl->authServers.push_back(authServer);
 +    }
 +}
 +
 +void AuthInstance::fillInRequestInfo(pjsip_rx_data *rdata, RequestInfoPtr &info)
 +{
 +    char buf[512];
 +    size_t pos;
 +
 +    pjsip_name_addr *from = (pjsip_name_addr *) rdata->msg_info.from->uri;
 +    info->fromName = std::string(pj_strbuf(&from->display), pj_strlen(&from->display));
 +
 +    mImpl->mLogger(Debug) << "from name is " << info->fromName;
 +
 +    pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, from->uri, buf, sizeof(buf));
 +    std::string fromURI(buf, strlen(buf));
 +    pos = fromURI.find_first_of(';');
 +    info->fromURI = fromURI.substr(0, pos);
 +
 +    mImpl->mLogger(Debug) << "from uri is " << info->fromURI;
 +
 +    if (pos != std::string::npos)
 +    {
 +        mImpl->getURIParams(from->uri, info->fromParams);
 +    }
 +
 +    pjsip_name_addr *to = (pjsip_name_addr *) rdata->msg_info.to->uri;
 +    info->toName = std::string(pj_strbuf(&to->display), pj_strlen(&to->display));
 +
 +    mImpl->mLogger(Debug) << "to name is " << info->toName;
 +
 +    pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, to->uri, buf, sizeof(buf));
 +    std::string toURI(buf, strlen(buf));
 +    pos = toURI.find_first_of(';');
 +    info->toURI = toURI.substr(0, pos);
 +
 +    mImpl->mLogger(Debug) << "to uri is " << info->toURI;
 +
 +    if (pos != std::string::npos)
 +    {
 +        mImpl->getURIParams(to->uri, info->toParams);
 +    }
 +
 +    pjsip_uri *rURI = static_cast<pjsip_uri *>(pjsip_uri_get_uri(rdata->msg_info.msg->line.req.uri));
 +    pjsip_uri_print(PJSIP_URI_IN_REQ_URI, rURI, buf, sizeof(buf));
 +    std::string rURIStr(buf, strlen(buf));
 +    pos = rURIStr.find_first_of(';');
 +    info->requestURI = rURIStr.substr(0, pos);
 +
 +    mImpl->mLogger(Debug) << "ruri is " << info->requestURI;
 +
 +    if (pos != std::string::npos)
 +    {
 +        mImpl->getURIParams(rURI, info->requestURIParams);
 +    }
 +
 +    info->IPAddr = std::string(pj_sockaddr_print(static_cast<pj_sockaddr_t *> (&rdata->pkt_info.src_addr),
 +                buf, rdata->pkt_info.src_addr_len, 0), rdata->pkt_info.src_addr_len);
 +    info->port = rdata->pkt_info.src_port;
 +    std::string transport(rdata->tp_info.transport->type_name);
 +    if (transport == "tcp")
 +    {
 +        info->transport = AsteriskSCF::SIP::ExtensionPoint::V1::TCP;
 +        mImpl->mLogger(Debug) << "Set transport to TCP";
 +    }
 +    else if (transport == "tls")
 +    {
 +        info->transport = AsteriskSCF::SIP::ExtensionPoint::V1::TLS;
 +        mImpl->mLogger(Debug) << "Set transport to TLS";
 +    }
 +    else if (transport == "udp")
 +    {
 +        info->transport = AsteriskSCF::SIP::ExtensionPoint::V1::UDP;
 +        mImpl->mLogger(Debug) << "Set transport to UDP";
 +    }
 +}
 +
 +bool AuthInstance::isEqual(const std::string &fromTag, const std::string &callId)
 +{
 +    return fromTag == mImpl->fromTag && callId == mImpl->callId;
 +}
 +
 +void AuthInstance::cancelAuthTimeout()
 +{
 +    pjsip_endpt_cancel_timer(mImpl->mEndpoint, &mImpl->entry);
 +}
 +
 +class AuthManagerPriv
 +{
 +public:
 +    AuthManagerPriv(pjsip_endpoint *endpt, const Logger &logger)
 +        : mEndpoint(endpt),
 +        mLogger(logger) { }
 +
 +    ~AuthManagerPriv()
 +    {
 +        mAuthInstances.erase(mAuthInstances.begin(), mAuthInstances.end());
 +    }
 +
 +    std::vector<boost::shared_ptr<AuthInstance> > mAuthInstances;
 +    pjsip_endpoint *mEndpoint;
 +    moduleHookVector mRegisteredHooks;
 +    Logger mLogger;
 +    int mCounter;
 +    boost::mutex mHooksLock;
 +    boost::mutex mAuthInstancesLock;
 +};
 +
 +AuthManager::AuthManager(pjsip_endpoint *endpt, const Logger &logger)
 +    : mImpl(new AuthManagerPriv(endpt, logger)) { }
 +
 +AuthManager::~AuthManager()
 +{
 +}
 +
 +boost::shared_ptr<AuthInstance> AuthManager::createAuthInstance(pjsip_rx_data *rdata, RequestType type)
 +{
 +    boost::shared_ptr<AuthInstance> instance;
 +    {
 +        boost::lock_guard<boost::mutex> hookLock(mImpl->mHooksLock);
 +        instance.reset(new AuthInstance(rdata, mImpl->mRegisteredHooks,
 +                type, mImpl->mEndpoint, mImpl->mLogger));
 +    }
 +    boost::lock_guard<boost::mutex> instancesLock(mImpl->mAuthInstancesLock);
 +    mImpl->mAuthInstances.push_back(instance);
 +    return instance;
 +}
 +
 +bool AuthManager::authenticate(pjsip_rx_data *rdata)
 +{
 +    const std::string fromTag(pj_strbuf(&rdata->msg_info.from->tag),
 +            pj_strlen(&rdata->msg_info.from->tag));
 +    const std::string callId(pj_strbuf(&rdata->msg_info.cid->id),
 +            pj_strlen(&rdata->msg_info.cid->id));
 +    boost::shared_ptr<AuthInstance> instance;
 +    boost::lock_guard<boost::mutex> lock(mImpl->mAuthInstancesLock);
 +    for (std::vector<boost::shared_ptr<AuthInstance> >::iterator iter = mImpl->mAuthInstances.begin();
 +            iter != mImpl->mAuthInstances.end(); ++iter)
 +    {
 +        if ((*iter)->isEqual(fromTag, callId))
 +        {
 +            if ((*iter)->authenticate(rdata))
 +            {
 +                //If authentication has succeeded, then we can remove this AuthInstance
 +                //from our list, and we need to cancel the scheduled task
 +                (*iter)->cancelAuthTimeout();
 +                mImpl->mAuthInstances.erase(iter);
 +                return true;
 +            }
 +            break;
 +        }
 +    }
 +    return false;
 +}
 +
 +void AuthManager::destroyAuthInstance(const boost::shared_ptr<AuthInstance> &instance)
 +{
 +    boost::lock_guard<boost::mutex> lock(mImpl->mAuthInstancesLock);
 +    for (std::vector<boost::shared_ptr<AuthInstance> >::iterator iter = mImpl->mAuthInstances.begin();
 +            iter != mImpl->mAuthInstances.end(); ++ iter)
 +    {
 +        if (*iter == instance)
 +        {
 +            mImpl->mAuthInstances.erase(iter);
 +            break;
 +        }
 +    }
 +}
 +
 +void AuthManager::scheduleAuthTimeout(const boost::shared_ptr<AuthInstance> &instance)
 +{
 +    instance->scheduleAuthTimeout(mImpl->mCounter++);
 +}
 +
- void AuthManager::authTimeout(pj_timer_heap_t *timer_heap, pj_timer_entry *entry)
++void AuthManager::authTimeout(pj_timer_heap_t *, pj_timer_entry *entry)
 +{
 +    boost::shared_ptr<AuthInstance> killMe(static_cast<AuthInstance *>(entry->user_data));
 +    destroyAuthInstance(killMe);
 +}
 +
 +void AuthManager::addAuthHook(const AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx &hook,
 +        int priority, const AsteriskSCF::SIP::ExtensionPoint::V1::RequestTypeSeq &types)
 +{
 +    boost::shared_ptr<AuthHookData> hookData(new AuthHookData(priority, hook, types));
 +    boost::lock_guard<boost::mutex> lock(mImpl->mHooksLock);
 +    mImpl->mRegisteredHooks.push_back(hookData);
 +    std::stable_sort(mImpl->mRegisteredHooks.begin(), mImpl->mRegisteredHooks.end());
 +}
 +
 +void AuthManager::removeAuthHook(const AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx &hook)
 +{
 +    boost::lock_guard<boost::mutex> lock(mImpl->mHooksLock);
 +    for (moduleHookVector::iterator iter = mImpl->mRegisteredHooks.begin();
 +            iter != mImpl->mRegisteredHooks.end(); ++iter)
 +    {
 +        if ((*iter)->mHook == hook)
 +        {
 +            mImpl->mRegisteredHooks.erase(iter);
 +            break;
 +        }
 +    }
 +}
 +
 +void AuthManager::clearAuthHooks()
 +{
 +    boost::lock_guard<boost::mutex> lock(mImpl->mHooksLock);
 +    mImpl->mRegisteredHooks.clear();
 +}
 +
 +};
 +};
diff --cc src/AuthManager.h
index 7832549,0000000..07930ab
mode 100644,000000..100644
--- a/src/AuthManager.h
+++ b/src/AuthManager.h
@@@ -1,179 -1,0 +1,183 @@@
 +/*
 + * Asterisk SCF -- An open-source communications framework.
 + *
 + * Copyright (C) 2011, Digium, Inc.
 + *
 + * See http://www.asterisk.org for more information about
 + * the Asterisk SCF project. Please do not directly contact
 + * any of the maintainers of this project for assistance;
 + * the project provides a web site, mailing lists and IRC
 + * channels for your use.
 + *
 + * This program is free software, distributed under the terms of
 + * the GNU General Public License Version 2. See the LICENSE.txt file
 + * at the top of the source tree.
 + */
 +
 +#pragma once
 +
 +#include <boost/shared_ptr.hpp>
 +#include <pjsip.h>
 +#include <pjlib.h>
 +
 +#include <AsteriskSCF/System/Hook/HookIf.h>
 +#include <AsteriskSCF/SIP/SIPExtensionPointIf.h>
 +#include <AsteriskSCF/logger.h>
 +
 +namespace AsteriskSCF
 +{
 +
 +namespace SipSessionManager
 +{
 +
 +class AuthHookData;
 +
 +typedef std::vector<boost::shared_ptr<AuthHookData> > moduleHookVector;
 +
 +void sessionAuthTimeout(pj_timer_heap_t *timer_heap, pj_timer_entry *entry);
 +
 +class AuthInstancePriv;
 +
 +/**
 + * An AuthInstance represents a single attempt of us
 + * as the authentication server to authenticate a
 + * SIP requester.
 + */
 +class AuthInstance
 +{
 +public:
-     AuthInstance(pjsip_rx_data *rdata,
-             const moduleHookVector &hooks,
-             AsteriskSCF::SIP::ExtensionPoint::V1::RequestType type,
-             pjsip_endpoint *endpoint,
-             const AsteriskSCF::System::Logging::Logger &logger);
 +
 +    /**
 +     * The AuthInstance is able to distill all of the registered hooks
 +     * down to a smaller list based on the request types that the hooks
 +     * service. This is a helper function to get the distilled
 +     * list of hooks.
 +     */
 +    std::vector<AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx> getHooks();
 +
 +    /**
 +     * This function is a convenience function to fill in the common
 +     * data elements of a RequestInfo class given incoming request
 +     * data.
 +     */
 +    void fillInRequestInfo(pjsip_rx_data *rdata, AsteriskSCF::SIP::ExtensionPoint::V1::RequestInfoPtr &info);
 +
 +    /**
 +     * Add digest information to an outgoing response
 +     */
 +    void addDigests(pjsip_tx_data *tdata, const AsteriskSCF::SIP::ExtensionPoint::V1::DigestChallengeSeq &digests);
 +
 +    /**
 +     * Attempt to authenticate an incoming request.
 +     *
 +     * It's most convenient to just call AuthManager::authenticate() so
 +     * that the proper AuthInstance may be found for you.
 +     */
 +    bool authenticate(pjsip_rx_data *rdata);
 +
 +    /**
 +     * Schedule the destruction of this AuthInstance.
 +     *
 +     * This will generally be called via AuthManager::scheduleAuthTimeout
 +     * so that the id parameter can be guaranteed to be unique per
 +     * AuthInstance.
 +     */
 +    void scheduleAuthTimeout(int id);
 +
 +    /**
 +     * Cancel the current scheduled auth timeout task on the AuthInstance.
 +     */
 +    void cancelAuthTimeout();
 +
 +    /**
 +     * Determine if this AuthInstance matches a message with the given
 +     * from tag and call-id.
 +     */
 +    bool isEqual(const std::string &fromTag, const std::string &callId);
++
++    friend class AuthManager;
 +private:
++
++    AuthInstance(pjsip_rx_data *rdata,
++            const moduleHookVector &hooks,
++            AsteriskSCF::SIP::ExtensionPoint::V1::RequestType type,
++            pjsip_endpoint *endpoint,
++            const AsteriskSCF::System::Logging::Logger &logger);
++
 +    boost::shared_ptr<AuthInstancePriv> mImpl;
 +};
 +
 +class AuthManagerPriv;
 +
 +/**
 + * The AuthManager contains all AuthInstances
 + * for a given PJSIP module. It also contains
 + * all of a PJSIP module's registered authentication
 + * hooks.
 + */
 +class AuthManager
 +{
 +public:
 +    AuthManager(pjsip_endpoint *endpt, const AsteriskSCF::System::Logging::Logger& logger);
 +    ~AuthManager();
 +    /**
 +     * Attempt to authenticate a request
 +     *
 +     * This will search through the AuthManager's AuthInstances to
 +     * attempt to authenticate the request.
 +     * XXX Note that since the current task at hand is just to set
 +     * up the extension point for authentication and not to actually
 +     * authenticate, this doesn't actually do anything useful.
 +     */
 +    bool authenticate(pjsip_rx_data *rdata);
 +    /**
 +     * Create a new AuthInstance
 +     *
-      * If a PJSIP module decides wants to challenge a requester, then
++     * If a PJSIP module wants to challenge a requester, then
 +     * it must create an AuthInstance in order to do so. Do not
 +     * construct AuthInstances directly, but rather use this function
 +     * so that the AuthManager will have a reference to the AuthInstance
 +     * for later.
 +     */
 +    boost::shared_ptr<AuthInstance> createAuthInstance(pjsip_rx_data *rdata, AsteriskSCF::SIP::ExtensionPoint::V1::RequestType type);
 +    /**
 +     * Schedule the destruction of an AuthInstance
 +     *
 +     * After challenging a requester for authentication information,
 +     * a PJSIP module should call this method. This will ensure that if
 +     * the requester does not attempt to authenticate or never succeeds
 +     * in authenticating, the AuthInstance will eventually be destroyed.
 +     */
 +    void scheduleAuthTimeout(const boost::shared_ptr<AuthInstance> &instance);
 +    /**
 +     * Destroy an AuthInstance
 +     * 
 +     * This method is handy for destroying an AuthInstance if one has been created,
 +     * but a failure condition occurs before a challenge can be sent to the
 +     * requesting UA.
 +     */
 +    void destroyAuthInstance(const boost::shared_ptr<AuthInstance> &instance);
 +    /**
 +     * This is the callback that scheduleAuthDestruction sets up.
 +     *
 +     * Do not call this method directly.
 +     */
 +    void authTimeout(pj_timer_heap_t *timer_heap, pj_timer_entry *entry);
 +    /**
 +     * Register a new authentication hook with the AuthManager
 +     */
 +    void addAuthHook(const AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx &hook, int priority, const AsteriskSCF::SIP::ExtensionPoint::V1::RequestTypeSeq &types);
 +    /**
 +     * Remove a registered authentication hook from the AuthManager
 +     */
 +    void removeAuthHook(const AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx &hook);
 +    /**
 +     * Remove all registered authentication hooks from the AuthManager
 +     */
 +    void clearAuthHooks();
 +private:
 +    boost::shared_ptr<AuthManagerPriv> mImpl;
 +};
 +
 +}; //end namespace SipSessionManager
 +}; //end namespace AsteriskSCF
diff --cc src/CMakeLists.txt
index 93a8dbb,5aa8e59..9ac151e
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@@ -27,8 -32,8 +32,10 @@@ asterisk_scf_component_add_file(SipSess
  asterisk_scf_component_add_file(SipSessionManager PJSipLoggingModule.cpp)
  asterisk_scf_component_add_file(SipSessionManager PJSipLoggingModuleConstruction.cpp)
  asterisk_scf_component_add_file(SipSessionManager PJSipLoggingModule.h)
 +asterisk_scf_component_add_file(SipSessionManager AuthManager.cpp)
 +asterisk_scf_component_add_file(SipSessionManager AuthManager.h)
+ asterisk_scf_component_add_file(SipSessionManager SipConfiguration.cpp)
+ asterisk_scf_component_add_file(SipSessionManager SipConfiguration.h)
  asterisk_scf_component_add_file(SipSessionManager SipStateReplicatorListener.cpp)
  asterisk_scf_component_add_file(SipSessionManager SipStateReplicator.h)
  asterisk_scf_component_add_slice(SipSessionManager ../local-slice/SipIf.ice)
diff --cc src/PJSipManager.cpp
index ce36bec,ffd2854..084ecb6
--- a/src/PJSipManager.cpp
+++ b/src/PJSipManager.cpp
@@@ -14,15 -14,12 +14,15 @@@
   * at the top of the source tree.
   */
  
- #include <IceUtil/UUID.h>
+ #include "PJSipManager.h"
  #include <AsteriskSCF/logger.h>
  
- #include "PJSipManager.h"
+ #include <boost/lexical_cast.hpp>
  
  using namespace AsteriskSCF::System::Logging;
 +using namespace AsteriskSCF::System::Hook::V1;
 +using namespace AsteriskSCF::SIP::ExtensionPoint::V1;
 +using namespace AsteriskSCF::Core::Discovery::V1;
  
  namespace
  {
diff --cc src/PJSipManager.h
index 016af2a,9138770..8fec6e7
--- a/src/PJSipManager.h
+++ b/src/PJSipManager.h
@@@ -21,13 -21,12 +21,14 @@@
  #include <pjlib.h>
  #include <pjsip.h>
  
+ #include <Ice/Ice.h>
+ 
  #include <boost/shared_ptr.hpp>
+ #include <boost/thread/locks.hpp>
  
- #include <AsteriskSCF/SmartProxy.h>
+ #include <AsteriskSCF/Discovery/SmartProxy.h>
 +#include <AsteriskSCF/SIP/SIPExtensionPointIf.h>
 +#include <AsteriskSCF/System/Hook/HookIf.h>
  
  #include "PJSipSessionModule.h"
  #include "PJSipLoggingModule.h"
@@@ -82,9 -82,21 +84,24 @@@ public
       * for logging incoming and outgoing SIP messages
       */
      void registerLoggingModule();
 +    void addAuthHook(const AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx &hook, int priority, const AsteriskSCF::SIP::ExtensionPoint::V1::RequestTypeSeq &types);
 +    void removeAuthHook(const AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx &hook);
 +    void clearAuthHooks();
+ 
+     /**
+      * Create a UDP transport.
+      */
+     pjsip_transport *createUDPTransport(std::string, int);
+ 
+     /**
+      * Create a TCP transport.
+      */
+     pjsip_tpfactory *createTCPTransport(std::string, int);
+ 
+     /**
+      * Create a TLS transport.
+      */
+     pjsip_tpfactory *createTLSTransport(std::string, int, pjsip_tls_setting*);
  private:
      static PJSipManager *mInstance;
      pjsip_endpoint *mEndpoint;
diff --cc src/PJSipSessionModule.cpp
index 3462438,74fe6f3..38a6837
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@@ -28,9 -21,17 +21,19 @@@
  #include "PJSipManager.h"
  #include "SipStateReplicator.h"
  
+ #include <IceUtil/UUID.h>
+ 
+ #include <AsteriskSCF/Core/Endpoint/EndpointIf.h>
+ #include <AsteriskSCF/Core/Routing/RoutingIf.h>
+ #include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
+ #include <AsteriskSCF/Media/MediaIf.h>
+ #include <AsteriskSCF/logger.h>
+ #include <AsteriskSCF/WorkQueue/WorkQueue.h>
+ #include <AsteriskSCF/WorkQueue/SuspendableWorkQueue.h>
+ 
  using namespace AsteriskSCF::System::Logging;
 +using namespace AsteriskSCF::SIP::ExtensionPoint::V1;
 +using namespace AsteriskSCF::System::Hook::V1;
  
  namespace
  {
@@@ -274,11 -161,11 +163,16 @@@ InviteSessionState PJSipSessionModInfo:
      return retState;
  }
  
 +void PJSipSessionModule::createAuthManager(pjsip_endpoint *endpt)
 +{
 +    mAuthManager.reset(new AuthManager(endpt, lg));
 +}
 +
+ SessionWorkPtr PJSipSessionModInfo::getSessionWork()
+ {
+     return mSessionWork;
+ }
+ 
  void PJSipSessionModule::replicateState(PJSipDialogModInfo *dlgInfo, PJSipTransactionModInfo *tsxInfo,
      PJSipSessionModInfo *sessionInfo)
  {
@@@ -430,66 -325,105 +332,165 @@@ pj_status_t PJSipSessionModule::unload(
      return PJ_SUCCESS;
  }
  
- bool PJSipSessionModule::checkAuth(pjsip_rx_data *rdata, pjsip_inv_session *inv, RequestType type, pjsip_endpoint *endpt)
++bool PJSipSessionModule::checkAuth(pjsip_rx_data *rdata, pjsip_inv_session *inv, RequestType type)
 +{
 +    //First, let's see if this message has some auth that we know about.
 +    if (mAuthManager->authenticate(rdata) == true)
 +    {
 +        //Oh yeah! Authentication succeeded!
 +        return false;
 +    }
 +
 +    boost::shared_ptr<AuthInstance> authInstance(mAuthManager->createAuthInstance(rdata, type));
 +    
 +    std::vector<AuthHookPrx> hooks = authInstance->getHooks();
 +    if (hooks.empty())
 +    {
 +        return false;
 +    }
 +
 +    RequestInfoPtr info(new InviteRequestInfo);
 +    authInstance->fillInRequestInfo(rdata, info);
 +
 +    //We have our RequestInfo created. Now start calling out to any registered hooks
 +    //
 +    //XXX While this seems like something that could be taken care of in either the
 +    //AuthInstance or AuthManager class, there are some specific issues with this.
 +    //For instance, in this case, we create the outgoing message using the inv_session,
 +    //whereas other PJSIP modules will either access the base dialog directly
 +    //or have a different layer of indirection instead of the inv_session.
 +    for (std::vector<AuthHookPrx>::iterator iter = hooks.begin(); iter != hooks.end(); ++iter)
 +    {
 +        DigestChallengeSeq digests;
 +        HookResult result;
 +        result = (*iter)->challengeRequest(info, digests);
 +        if (result.status == Failed)
 +        {
 +            lg(Error) << "SIP Authentication hook reported a failure: " << result.info;
 +        }
 +        else if (result.status == Succeeded)
 +        {
 +            if (digests.empty())
 +            {
 +                //Hook says not to challenge. This AuthInstance
 +                //is deader than dead.
 +                mAuthManager->destroyAuthInstance(authInstance);
 +                return false;
 +            }
 +
 +            pjsip_tx_data *tdata;
 +            pjsip_inv_end_session(inv, 401, NULL, &tdata);
 +
 +            authInstance->addDigests(tdata, digests);
 +
 +            pjsip_inv_send_msg(inv, tdata);
 +
 +            mAuthManager->scheduleAuthTimeout(authInstance);
 +            return true;
 +        }
 +    }
 +    return false;
 +}
 +
+ class SessionCreationOperation : public SipQueueableOperation
+ {
+ public:
+     SessionCreationOperation(
+             const PJSipSessionModulePtr& module,
+             const SipEndpointPtr& caller,
+             const AsteriskSCF::Discovery::SmartProxy<SessionRouterPrx>& router,
+             pjsip_inv_session *inv,
+             pjsip_tx_data *tdata,
+             pjsip_dialog *replacedDialog,
+             const std::string destination)
+         : mSessionModule(module), mCaller(caller), mSessionRouter(router), mInv(inv), mTdata(tdata), mReplacedDialog(replacedDialog), mDestination(destination) { }
+ 
+ protected:
+     SuspendableWorkResult initial(const SuspendableWorkListenerPtr&)
+     {
+         lg(Debug) << "Executing SessionCreationOperation" << std::endl;
+         try
+         {
+             mSession = mCaller->createSession(mDestination);
+         }
+         catch (const Ice::Exception& ex)
+         {
+             lg(Error) << "Exception caught while trying to create SIP session\n" << ex.what();
+             pjsip_inv_end_session(mInv, 500, NULL, &mTdata);
+             pjsip_inv_send_msg(mInv, mTdata);
+             return Complete;
+         }
+         mSession->setInviteSession(mInv);
+         mSession->setDialog(mInv->dlg);
+         PJSipDialogModInfo *dlg_mod_info =(PJSipDialogModInfo*)mInv->dlg->mod_data[mSessionModule->getModule().id];
+         PJSipTransactionModInfo *tsx_mod_info = (PJSipTransactionModInfo *)mInv->invite_tsx->mod_data[mSessionModule->getModule().id];
+         PJSipSessionModInfo *session_mod_info = (PJSipSessionModInfo*)mInv->mod_data[mSessionModule->getModule().id];
+         // Now we can actually set a for-real non-NULL session on the session module information.
+         session_mod_info->setSessionPtr(mSession);
+ 
+         dlg_mod_info->mPending = false;
+ 
+         session_mod_info->updateSessionState(mInv);
+     
+         lg(Debug) << "Replicating state on reception of new SIP INVITE.";
+         mSessionModule->replicateState(dlg_mod_info, tsx_mod_info, session_mod_info);
+         try
+         {
+             if (mReplacedDialog)
+             {
+                 // For attended transfers we need to contact the routing service which should then (hopefully) replace the
+                 // other session
+             }
+             else
+             {
+                 // If this is not an attended transfer we can just route the session as normally
+                 std::string operationId = ::IceUtil::generateUUID();
+                 SuspendableWorkListenerPtr listener = 0;
+                 SipAMICallbackPtr cb(new SipAMICallback(listener, mSession, this, false, true));
+                 Ice::CallbackPtr d = Ice::newCallback(cb, &SipAMICallback::callback);
+                 mSessionRouter->begin_routeSession(operationId, mSession->getSessionProxy(), mDestination, d);
+             }
+         }
+         catch (const Ice::CommunicatorDestroyedException &)
+         {
+             // Everything else doesn't really map so they just become internal server errors
+             pjsip_inv_end_session(mInv, 500, NULL, &mTdata);
+             pjsip_inv_send_msg(mInv, mTdata);
+         }
+         return Complete;
+     }
+ 
+     SuspendableWorkResult calledBack(const SuspendableWorkListenerPtr&)
+     {
+         SessionRouterPrx router = SessionRouterPrx::uncheckedCast(mAsyncResult->getProxy());
+         try
+         {
+             router->end_routeSession(mAsyncResult);
+         }
+         catch (const DestinationNotFoundException &)
+         {
+             pjsip_inv_end_session(mInv, 404, NULL, &mTdata);
+             pjsip_inv_send_msg(mInv, mTdata);
+         }
+         catch (...)
+         {
+             pjsip_inv_end_session(mInv, 500, NULL, &mTdata);
+             pjsip_inv_send_msg(mInv, mTdata);
+         }
+         return Complete;
+     }
+ 
+ private:
+     PJSipSessionModulePtr mSessionModule;
+     SipEndpointPtr mCaller;
+     AsteriskSCF::Discovery::SmartProxy<SessionRouterPrx> mSessionRouter;
+     pjsip_inv_session *mInv;
+     pjsip_tx_data *mTdata;
+     pjsip_dialog *mReplacedDialog;
+     const std::string mDestination;
+     SipSessionPtr mSession;
+ };
+ 
  void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
  {
      //What do we do here?
@@@ -562,15 -536,6 +603,15 @@@
          pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
      }
  
-     bool authSent = checkAuth(rdata, inv_session, DialogEstablishing, dlg->endpt);
++    bool authSent = checkAuth(rdata, inv_session, DialogEstablishing);
 +
 +    // This means we sent a 401 to the requester,
 +    // so no need to go any further
 +    if (authSent)
 +    {
 +        return;
 +    }
 +
      pjsip_uri *from = rdata->msg_info.from->uri;
      std::string callerName("");
      if (PJSIP_URI_SCHEME_IS_SIP(from) || PJSIP_URI_SCHEME_IS_SIPS(from))
@@@ -1233,10 -1523,120 +1599,125 @@@ pjsip_dialog *PJSipSessionModule::uaOnD
      return NULL;
  }
  
 +void PJSipSessionModule::authTimeout(pj_timer_heap_t *timer_heap, pj_timer_entry *entry)
 +{
 +    mAuthManager->authTimeout(timer_heap, entry);
 +}
 +
+ QueuePtr PJSipSessionModule::getThreadPoolQueue()
+ {
+     return mPoolQueue;
+ }
+ 
+ void PJSipSessionModule::enqueueSessionWork(const SuspendableWorkPtr& work, pjsip_inv_session *inv)
+ {
+     PJSipSessionModInfo *session_mod_info =
+         static_cast<PJSipSessionModInfo*>(inv->mod_data[mModule.id]);
+ 
+     if (session_mod_info)
+     {
+         SessionWorkPtr sessionWork = session_mod_info->getSessionWork();
+         sessionWork->enqueueWork(work);
+     }
+ }
+ 
+ PJSipSessionModuleThreadPoolListener::PJSipSessionModuleThreadPoolListener()
+     : mActiveThreads(0), mPjLibHook(new pjlibHook()) { }
+ 
+ void PJSipSessionModuleThreadPoolListener::stateChanged(const PoolPtr& pool, Ice::Long active, Ice::Long idle, Ice::Long)
+ {
+     //XXX Making this behavior more customizable would be nice
+     //
+     //For now, what we do is kill all idle threads.
+     if (idle > 0)
+     {
+         pool->setSize((int) active);
+     }
+     mActiveThreads = active;
+ }
+ 
+ void PJSipSessionModuleThreadPoolListener::queueWorkAdded(const PoolPtr& pool, Ice::Long numNewWork, bool)
+ {
+     //XXX Making this behavior more customizable would be nice
+     //
+     //For now, use one thread per work item.
+ 
+     lg(Debug) << "Detected the addition of work to SIP's thread pool. Setting the size to " << mActiveThreads + numNewWork;
+     int newSize = (int) (mActiveThreads + numNewWork);
+     pool->setSize(newSize);
+ }
+ 
+ void PJSipSessionModuleThreadPoolListener::queueEmptied(const PoolPtr& pool)
+ {
+     //XXX Making this behavior more customizable would be nice
+     //
+     //For now, kill off everything
+ 
+     lg(Debug) << "The queue is empty so we're killing all the threads";
+     pool->setSize(0);
+ }
+ 
+ void PJSipSessionModuleThreadPoolListener::threadStart()
+ {
+     lg(Debug) << "New thread created. Registering it with PJLIB";
+     mPjLibHook->start();
+ }
+ 
+ void PJSipSessionModuleThreadPoolListener::threadStop()
+ {
+     lg(Debug) << "Thread has completed. Unregistering it from PJLIB";
+     mPjLibHook->stop();
+ }
+ 
+ class SipSessionSuspendableWorkListener : public SuspendableWorkListener
+ {
+ public:
+     SipSessionSuspendableWorkListener(const QueueListenerPtr& queueListener)
+         : mQueueListener(queueListener) { }
+ 
+     void workResumable()
+     {
+         mQueueListener->workResumable();
+     }
+ 
+ private:
+     QueueListenerPtr mQueueListener;
+ };
+ 
+ SessionWork::SessionWork(const QueuePtr& queue)
+     : mThreadPoolQueue(queue),
+     mInternalQueue(new SuspendableWorkQueue(this)) { }
+ 
+ void SessionWork::workAdded(Ice::Long, bool wasEmpty)
+ {
+     if (wasEmpty)
+     {
+         mThreadPoolQueue->enqueueWork(this);
+     }
+ }
+ 
+ void SessionWork::workResumable()
+ {
+     mThreadPoolQueue->enqueueWork(this);
+ }
+ 
+ void SessionWork::emptied()
+ {
+     //Empty on purpose. Nothing special
+     //to do here.
+ }
+ 
+ void SessionWork::execute()
+ {
+     while(mInternalQueue->executeWork()) {
+         // no-op
+     }
+ }
+ 
+ void SessionWork::enqueueWork(const SuspendableWorkPtr& work)
+ {
+     mInternalQueue->enqueueWork(work);
+ }
+ 
  }; //end namespace SipSessionManager
  }; //end namespace AsteriskSCF
diff --cc src/PJSipSessionModule.h
index a5a613a,73fd186..7c46aba
--- a/src/PJSipSessionModule.h
+++ b/src/PJSipSessionModule.h
@@@ -80,16 -109,17 +109,21 @@@ public
      pjsip_redirect_op invOnRedirected(pjsip_inv_session *inv, const pjsip_uri *target, const pjsip_event *e);
      pjsip_dialog *uaOnDialogForked(pjsip_dialog *first_set, pjsip_rx_data *rdata);
      // Missing onsendack for now
 +    void authTimeout(pj_timer_heap_t *timer_heap, pj_timer_entry *entry);
      void replicateState(PJSipDialogModInfo *dlgInfo, PJSipTransactionModInfo *tsxInfo,
          PJSipSessionModInfo *sessionInfo);
+     void enqueueSessionWork(
+             const AsteriskSCF::System::WorkQueue::V1::SuspendableWorkPtr&,
+             pjsip_inv_session *);
+ 
+     AsteriskSCF::System::WorkQueue::V1::QueuePtr getThreadPoolQueue();
  private:
      void handleNewInvite(pjsip_rx_data *rdata);
      void handleInviteResponse(pjsip_inv_session *inv, pjsip_rx_data *rdata, pjsip_dialog *dlg);
      void handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdata);
-     bool checkAuth(pjsip_rx_data *rdata, pjsip_inv_session *inv, AsteriskSCF::SIP::ExtensionPoint::V1::RequestType type, pjsip_endpoint *endpt);
++    bool checkAuth(pjsip_rx_data *rdata, pjsip_inv_session *inv, AsteriskSCF::SIP::ExtensionPoint::V1::RequestType type);
 +    void getURIParams(pjsip_uri *uri, AsteriskSCF::SIP::ExtensionPoint::V1::ParamDict &params);
 +    void createAuthManager(pjsip_endpoint *endpt);
      pjsip_inv_callback mInvCallback;
      pjsip_ua_init_param mUaParam;
      const std::string mName;
diff --cc src/PJSipSessionModuleConstruction.cpp
index 905f35d,14e0718..1efdfea
--- a/src/PJSipSessionModuleConstruction.cpp
+++ b/src/PJSipSessionModuleConstruction.cpp
@@@ -14,8 -14,10 +14,11 @@@
   * at the top of the source tree.
   */
  
+ #include <AsteriskSCF/WorkQueue/WorkQueue.h>
+ #include <AsteriskSCF/ThreadPool/ThreadPool.h>
+ 
  #include "PJSipSessionModule.h"
 +#include "AuthManager.h"
  
  namespace AsteriskSCF
  {
@@@ -92,20 -97,15 +98,20 @@@ static pjsip_dialog *uaOnDialogForked(p
      return sessionModule->uaOnDialogForked(first_set, rdata);
  }
  
 +void sessionAuthTimeout(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
 +{
 +    return sessionModule->authTimeout(timer_heap, entry);
 +}
 +
  PJSipSessionModule::PJSipSessionModule(pjsip_endpoint *endpt,
-     boost::shared_ptr<SipEndpointFactory> endpointFactoryPtr,
-     AsteriskSCF::SmartProxy::SmartProxy<AsteriskSCF::SessionCommunications::V1::SessionRouterPrx> sessionRouter,
-     AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx serviceLocator,
-     AsteriskSCF::SmartProxy::SmartProxy<AsteriskSCF::SIP::V1::SipStateReplicatorPrx> stateReplicator,
-     AsteriskSCF::System::Component::V1::ReplicaPtr replica)
+     const boost::shared_ptr<SipEndpointFactory>& endpointFactoryPtr,
+     const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::SessionCommunications::V1::SessionRouterPrx>& sessionRouter,
+     const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
+     const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::SIP::V1::SipStateReplicatorPrx>& stateReplicator,
+     const AsteriskSCF::System::Component::V1::ReplicaPtr& replica)
      : mName(moduleName), mEndpointFactory(endpointFactoryPtr),
        mSessionRouter(sessionRouter), mServiceLocator(serviceLocator),
-       mStateReplicator(stateReplicator), mReplica(replica)
+       mStateReplicator(stateReplicator), mReplica(replica), mEndpoint(endpt)
  {
      sessionModule = this;
      mModule.name = pj_str(moduleName);
@@@ -146,8 -152,8 +158,9 @@@
      pjsip_evsub_init_module(endpt);
      pjsip_xfer_init_module(endpt);
      pjsip_replaces_init_module(endpt);
+     pjsip_timer_init_module(endpt);
      pjsip_endpt_register_module(endpt, &mModule);
 +    createAuthManager(endpt);
  }
  
  }; //end namespace SipSessionManager
diff --cc src/SipSessionManagerApp.cpp
index 225695d,7e4bb4e..9bdbed5
--- a/src/SipSessionManagerApp.cpp
+++ b/src/SipSessionManagerApp.cpp
@@@ -49,10 -52,8 +52,10 @@@ using namespace AsteriskSCF::Core::Rout
  using namespace AsteriskSCF::Core::Discovery::V1;
  using namespace AsteriskSCF::System::Component::V1;
  using namespace AsteriskSCF::System::Logging;
 +using namespace AsteriskSCF::System::Hook::V1;
  using namespace AsteriskSCF::SessionCommunications::V1;
- using namespace AsteriskSCF::SmartProxy;
 +using namespace AsteriskSCF::SIP::ExtensionPoint::V1;
+ using namespace AsteriskSCF::System::Configuration::V1;
  
  namespace
  {
@@@ -146,21 -116,23 +150,25 @@@ private
  
      ServiceLocatorManagementPrx mServiceLocatorManagement;
  
-     Discovery::V1::ServiceManagementPrx mComponentServiceManagement;
-     Discovery::V1::ServiceManagementPrx mAuthServiceManagement;
+     ServiceManagementPrx mComponentServiceManagement;
+     ServiceManagementPrx mConfigurationManagement;
++    ServiceManagementPrx mAuthServiceManagement;
+     std::string mConfigCompareGuid;
      ReplicaPtr mReplicaService;
      ComponentServicePtr mComponentService;
+     ConfigurationServicePtr mConfigurationService;
+     ConfigurationServicePrx mConfigurationServiceProxy;
      PJSipManager *mPJSipManager;
      SipStateReplicatorListenerPtr mReplicatorListener;
      SipStateReplicatorListenerPrx mReplicatorListenerProxy;
      boost::shared_ptr<SipEndpointFactory> mEndpointFactory;
      ServiceLocatorPrx mServiceLocator;
-     AsteriskSCF::SmartProxy::SmartProxy<SipStateReplicatorPrx> mStateReplicator;
-     AsteriskSCF::SmartProxy::SmartProxy<SessionRouterPrx> mSessionRouter;
-     AsteriskSCF::SmartProxy::SmartProxy<LocatorRegistryPrx> mRoutingServiceLocatorRegistry;
+     AsteriskSCF::Discovery::SmartProxy<SipStateReplicatorPrx> mStateReplicator;
+     AsteriskSCF::Discovery::SmartProxy<SessionRouterPrx> mSessionRouter;
+     AsteriskSCF::Discovery::SmartProxy<LocatorRegistryPrx> mRoutingServiceLocatorRegistry;
      boost::shared_ptr<SipSessionManagerEventPublisher> mEventPublisher;
      Routing::V1::EndpointLocatorPtr mEndpointLocator;
 +    SipAuthExtensionPointPtr mAuthService;
  };
  
  static const string ComponentServiceId("SipChannelComponent");
@@@ -349,13 -298,28 +335,35 @@@ void SipSessionManager::registerWithSer
  
          setCategory(mComponentServiceManagement, AsteriskSCF::SIP::V1::ComponentServiceDiscoveryCategory);
  
 -	if (mCommunicator->getProperties()->getPropertyWithDefault("Sip.Standalone", "false") == "true")
 -	{
 -	    // Publish the configuration service IceStorm topic so everybody gets configuration
 -	    mConfigurationManagement = ServiceManagementPrx::uncheckedCast(
 -		mServiceLocatorManagement->addService(mConfigurationServiceProxy, ""));
 -
 -	    // Populate the configuration parameters with details so we can be found
 -	    SipConfigurationParamsPtr configurationParams = new SipConfigurationParams();
 -	    configurationParams->category = ConfigurationDiscoveryCategory;
 -	    configurationParams->name = mCommunicator->getProperties()->getPropertyWithDefault("SipConfiguration.Name", "");
 -
 -	    // Add our custom comparator so we can support multiple simultaneous configuration sinks
 -	    SipConfigurationComparePtr configNameCompare = new SipConfigurationCompare(configurationParams->name);
 -	    ServiceLocatorParamsComparePrx configCompareProxy = ServiceLocatorParamsComparePrx::uncheckedCast(
 -		mLocalAdapter->addWithUUID(configNameCompare));
 -
 -	    mConfigCompareGuid = IceUtil::generateUUID();
 -	    mServiceLocatorManagement->addCompare(mConfigCompareGuid, configCompareProxy);
 -	    mConfigurationManagement->addLocatorParams(configurationParams, mConfigCompareGuid);
 -	}
 +        // Hey look we have an Auth extension point to publish!
 +        Ice::ObjectPrx authObjPrx = mLocalAdapter->createDirectProxy(mCommunicator->stringToIdentity(AuthServiceId));
 +        AuthExtensionPointPrx authPrx = AuthExtensionPointPrx::checkedCast(authObjPrx);
 +
 +        std::string authServiceGuid("SipAuthExtensionPoint");
 +        mAuthServiceManagement = ServiceManagementPrx::uncheckedCast(mServiceLocatorManagement->addService(authPrx, authServiceGuid));
 +        setCategory(mAuthServiceManagement, AsteriskSCF::SIP::V1::AuthExtensionPointCategory);
++        if (mCommunicator->getProperties()->getPropertyWithDefault("Sip.Standalone", "false") == "true")
++        {
++            // Publish the configuration service IceStorm topic so everybody gets configuration
++            mConfigurationManagement = ServiceManagementPrx::uncheckedCast(
++        	mServiceLocatorManagement->addService(mConfigurationServiceProxy, ""));
++        
++            // Populate the configuration parameters with details so we can be found
++            SipConfigurationParamsPtr configurationParams = new SipConfigurationParams();
++            configurationParams->category = ConfigurationDiscoveryCategory;
++            configurationParams->name = mCommunicator->getProperties()->getPropertyWithDefault("SipConfiguration.Name", "");
++        
++            // Add our custom comparator so we can support multiple simultaneous configuration sinks
++            SipConfigurationComparePtr configNameCompare = new SipConfigurationCompare(configurationParams->name);
++            ServiceLocatorParamsComparePrx configCompareProxy = ServiceLocatorParamsComparePrx::uncheckedCast(
++        	mLocalAdapter->addWithUUID(configNameCompare));
++        
++            mConfigCompareGuid = IceUtil::generateUUID();
++            mServiceLocatorManagement->addCompare(mConfigCompareGuid, configCompareProxy);
++            mConfigurationManagement->addLocatorParams(configurationParams, mConfigCompareGuid);
++        }
+ 
+         // TBD... We may have other interfaces to publish to the Service Locator.
      }
      catch(...)
      {
@@@ -581,14 -578,10 +622,15 @@@ void SipSessionManager::initialize(cons
          mLocalAdapter->add(mComponentService, mCommunicator->stringToIdentity(ComponentServiceId));
          lg(Debug) << "Added component service to object adapter";
  
 +        // Create and publish our AuthExtensionPoint
 +        mAuthService = new SipAuthExtensionPoint(mPJSipManager);
 +        mLocalAdapter->add(mAuthService, mCommunicator->stringToIdentity(AuthServiceId));
 +        lg(Debug) << "Added Auth extension point to object adapter";
 +
          // Create and publish our state replicator listener interface.
          mReplicatorListener = new SipStateReplicatorListenerI(mEndpointFactory, mPJSipManager);
-         mReplicatorListenerProxy = SipStateReplicatorListenerPrx::uncheckedCast(mLocalAdapter->addWithUUID(mReplicatorListener));
+         mReplicatorListenerProxy =
+             SipStateReplicatorListenerPrx::uncheckedCast(mLocalAdapter->addWithUUID(mReplicatorListener));
          lg(Debug) << "Got proxy to SIP state replicator";
  
          mGlobalAdapter->activate();

-----------------------------------------------------------------------


-- 
asterisk-scf/release/sip.git



More information about the asterisk-scf-commits mailing list