Beispiel #1
0
/*
 * Verify parameters for OSP module
 * return 0 success, -1 failure
 */
static int ospVerifyParameters(void)
{
    int i;
    char hostname[OSP_STRBUF_SIZE];
    int result = 0;

    if ((_osp_work_mode < 0) || (_osp_work_mode > 1)) {
        _osp_work_mode = OSP_DEF_MODE;
        LM_WARN("work mode is out of range, reset to %d\n", OSP_DEF_MODE);
    }

    if ((_osp_service_type < 0) || (_osp_service_type > 3)) {
        _osp_service_type = OSP_DEF_SERVICE;
        LM_WARN("service type is out of range, reset to %d\n", OSP_DEF_SERVICE);
    }

    _osp_sp_number = 0;
    for (i = 0; i < OSP_DEF_SPS; i++) {
        if (_osp_sp_uris[i] != NULL) {
            if (_osp_sp_number != i) {
                _osp_sp_uris[_osp_sp_number] = _osp_sp_uris[i];
                _osp_sp_weights[_osp_sp_number] = _osp_sp_weights[i];
                _osp_sp_uris[i] = NULL;
                _osp_sp_weights[i] = OSP_DEF_WEIGHT;
            }
            osp_index[_osp_sp_number] = i + 1;
            _osp_sp_number++;
        }
    }

    if (_osp_sp_number == 0) {
        LM_ERR("at least one service point uri must be configured\n");
        result = -1;
    }

    if (_osp_device_ip == NULL) {
        gethostname(hostname, sizeof(hostname));
        _osp_device_ip = hostname;
    }
    ospConvertToOutAddress(_osp_device_ip, _osp_out_device, sizeof(_osp_out_device));
    ospConvertToInAddress(_osp_device_ip, _osp_in_device, sizeof(_osp_in_device));

    /* If use_security_features is 0, ignroe the certificate files */
    if (_osp_use_security != 0) {
        /* Default location for the cert files is in the compile time variable CFG_DIR */
        if (_osp_private_key == NULL) {
            sprintf(_osp_PRIVATE_KEY, "%spkey.pem", CFG_DIR);
            _osp_private_key = _osp_PRIVATE_KEY;
        }

        if (_osp_local_certificate == NULL) {
            sprintf(_osp_LOCAL_CERTIFICATE, "%slocalcert.pem", CFG_DIR);
            _osp_local_certificate = _osp_LOCAL_CERTIFICATE;
        }

        if (_osp_ca_certificate == NULL) {
            sprintf(_osp_CA_CERTIFICATE, "%scacert_0.pem", CFG_DIR);
            _osp_ca_certificate = _osp_CA_CERTIFICATE;
        }
    }

    if (_osp_token_format < 0 || _osp_token_format > 2) {
        _osp_token_format = OSP_DEF_TOKEN;
        LM_WARN("token_format is out of range, reset to %d\n", OSP_DEF_TOKEN);
    }

    if (_osp_max_dests > OSP_DEF_DESTS || _osp_max_dests < 1) {
        _osp_max_dests = OSP_DEF_DESTS;
        LM_WARN("max_destinations is out of range, reset to %d\n", OSP_DEF_DESTS);
    }

    if (_osp_report_nid < 0 || _osp_report_nid > 3) {
        _osp_report_nid = OSP_DEF_REPORTNID;
        LM_WARN("report_networkid is out of range, reset to %d\n", OSP_DEF_REPORTNID);
    }

    if (_osp_use_np < 0 || _osp_use_np > 1) {
        _osp_use_np = OSP_DEF_USENP;
        LM_WARN("use_number_portability is out of range, reset to %d\n", OSP_DEF_USENP);
    }

    if (_osp_export_np < 0 || _osp_export_np > 1) {
        _osp_export_np = OSP_DEF_EXPORTNP;
        LM_WARN("export_npparameter_order is out of range, reset to %d\n", OSP_DEF_EXPORTNP);
    }

    if (_osp_append_userphone < 0 || _osp_append_userphone > 1) {
        _osp_append_userphone = OSP_DEF_USERPHONE;
        LM_WARN("append_userphone is out of range, reset to %d\n", OSP_DEF_USERPHONE);
    }

    if ((_osp_dnid_location < 0) || (_osp_dnid_location > 2)) {
        _osp_dnid_location = OSP_DEF_DNIDLOC;
        LM_WARN("networkid_location is out of range, reset to %d\n", OSP_DEF_DNIDLOC);
    }

    if (!(_osp_dnid_param && *_osp_dnid_param)) {
        _osp_dnid_param = OSP_DEF_DNIDPARAM;
    }

    if ((_osp_swid_location < 0) || (_osp_swid_location > 2)) {
        _osp_swid_location = OSP_DEF_SWIDLOC;
        LM_WARN("switchid_location is out of range, reset to %d\n", OSP_DEF_SWIDLOC);
    }

    if (!(_osp_swid_param && *_osp_swid_param)) {
        _osp_swid_param = OSP_DEF_SWIDPARAM;
    }

    if ((_osp_paramstr_location < 0) || (_osp_paramstr_location > 2)) {
        _osp_paramstr_location = OSP_DEF_PARAMSTRLOC;
        LM_WARN("parameterstring_location is out of range, reset to %d\n", OSP_DEF_PARAMSTRLOC);
    }

    if (!(_osp_paramstr_value && *_osp_paramstr_value)) {
        _osp_paramstr_value = OSP_DEF_PARAMSTRVAL;
    }

    ospCheckAVP(_osp_srcdev_avp, &_osp_srcdev_avpid, &_osp_srcdev_avptype);

    ospCheckAVP(_osp_snid_avp, &_osp_snid_avpid, &_osp_snid_avptype);

    ospCheckAVP(_osp_swid_avp, &_osp_swid_avpid, &_osp_swid_avptype);

    ospCheckAVP(_osp_cinfo_avp, &_osp_cinfo_avpid, &_osp_cinfo_avptype);

    ospCheckAVP(_osp_cnam_avp, &_osp_cnam_avpid, &_osp_cnam_avptype);

    if (!(_osp_extraheaders_value && *_osp_extraheaders_value)) {
        _osp_extraheaders_value = OSP_DEF_EXTHEADERVAL;
    }

    ospCheckAVP(_osp_srcmedia_avp, &_osp_srcmedia_avpid, &_osp_srcmedia_avptype);
    ospCheckAVP(_osp_destmedia_avp, &_osp_destmedia_avpid, &_osp_destmedia_avptype);

    ospCheckAVP(_osp_reqdate_avp, &_osp_reqdate_avpid, &_osp_reqdate_avptype);
    ospCheckAVP(_osp_sdpfp_avp, &_osp_sdpfp_avpid, &_osp_sdpfp_avptype);
    ospCheckAVP(_osp_identity_avp, &_osp_identity_avpid, &_osp_identity_avptype);

    ospCheckAVP(_osp_sp_avp, &_osp_sp_avpid, &_osp_sp_avptype);
    ospCheckAVP(_osp_usergroup_avp, &_osp_usergroup_avpid, &_osp_usergroup_avptype);
    ospCheckAVP(_osp_userid_avp, &_osp_userid_avpid, &_osp_userid_avptype);

    ospCheckAVP(_osp_dest_avp, &_osp_dest_avpid, &_osp_dest_avptype);

    ospCheckAVP(_osp_reasontype_avp, &_osp_reasontype_avpid, &_osp_reasontype_avptype);
    ospCheckAVP(_osp_reasoncause_avp, &_osp_reasoncause_avpid, &_osp_reasoncause_avptype);
    ospCheckAVP(_osp_reasontext_avp, &_osp_reasontext_avpid, &_osp_reasontext_avptype);

    ospDumpParameters();

    return result;
}
/*
 * Get routes from AuthRsp
 * param transaction Transaction handle
 * param destcount Expected destination count
 * param inbound Inbound info
 * return 0 success, -1 failure
 */
static int ospLoadRoutes(
    OSPTTRANHANDLE trans,
    int destcount,
    osp_inbound* inbound)
{
    int count;
    int errcode;
    osp_dest* dest;
    osp_dest dests[OSP_DEF_DESTS];
    char host[OSP_STRBUF_SIZE];
    char destdev[OSP_STRBUF_SIZE];
    OSPE_OPERATOR_NAME type;
    OSPE_DEST_OSPENABLED enabled;
    int result = 0;

    ospSetIdentity(trans);

    for (count = 0; count < destcount; count++) {
        /* This is necessary because we will save destinations in reverse order */
        dest = ospInitDestination(&dests[count]);

        if (dest == NULL) {
            result = -1;
            break;
        }

        dest->destcount = count + 1;

        if (count == 0) {
            errcode = OSPPTransactionGetFirstDestination(
                trans,
                sizeof(dest->validafter),
                dest->validafter,
                dest->validuntil,
                &dest->timelimit,
                &dest->callidsize,
                (void*)dest->callid,
                sizeof(dest->called),
                dest->called,
                sizeof(dest->calling),
                dest->calling,
                sizeof(host),
                host,
                sizeof(destdev),
                destdev,
                &dest->tokensize,
                dest->token);
        } else {
            errcode = OSPPTransactionGetNextDestination(
                trans,
                0,
                sizeof(dest->validafter),
                dest->validafter,
                dest->validuntil,
                &dest->timelimit,
                &dest->callidsize,
                (void*)dest->callid,
                sizeof(dest->called),
                dest->called,
                sizeof(dest->calling),
                dest->calling,
                sizeof(host),
                host,
                sizeof(destdev),
                destdev,
                &dest->tokensize,
                dest->token);
        }

        if (errcode != OSPC_ERR_NO_ERROR) {
            LM_ERR("failed to load routes (%d) expected '%d' current '%d'\n",
                errcode,
                destcount,
                count);
            result = -1;
            break;
        }

        ospConvertToInAddress(host, dest->host, sizeof(dest->host));

        errcode = OSPPTransactionGetNumberPortabilityParameters(trans,
            sizeof(dest->nprn),
            dest->nprn,
            sizeof(dest->npcic),
            dest->npcic,
            &dest->npdi);
        if (errcode != OSPC_ERR_NO_ERROR) {
            LM_DBG("cannot get number portability parameters (%d)\n", errcode);
            dest->nprn[0] = '\0';
            dest->npcic[0] = '\0';
            dest->npdi = 0;
        }

        for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
            errcode = OSPPTransactionGetOperatorName(trans,
                type,
                sizeof(dest->opname[type]),
                dest->opname[type]);
            if (errcode != OSPC_ERR_NO_ERROR) {
                LM_DBG("cannot get operator name '%d' (%d)\n", type, errcode);
                dest->opname[type][0] = '\0';
            }
        }

        errcode = OSPPTransactionGetDestProtocol(trans, &dest->protocol);
        if (errcode != OSPC_ERR_NO_ERROR) {
            /* This does not mean an ERROR. The OSP server may not support OSP 2.1.1 */
            LM_DBG("cannot get dest protocol (%d)\n", errcode);
            dest->protocol = OSPC_PROTNAME_SIP;
        }
        switch (dest->protocol) {
            case OSPC_PROTNAME_Q931:
            case OSPC_PROTNAME_LRQ:
            case OSPC_PROTNAME_IAX:
            case OSPC_PROTNAME_T37:
            case OSPC_PROTNAME_T38:
            case OSPC_PROTNAME_SKYPE:
            case OSPC_PROTNAME_SMPP:
            case OSPC_PROTNAME_XMPP:
                if (_osp_non_sip) {
                    dest->supported = 1;
                } else {
                    dest->supported = 0;
                }
                break;
            case OSPC_PROTNAME_SIP:
            case OSPC_PROTNAME_UNDEFINED:
            case OSPC_PROTNAME_UNKNOWN:
            default:
                dest->supported = 1;
                break;
        }

        errcode = OSPPTransactionIsDestOSPEnabled(trans, &enabled);
        if (errcode != OSPC_ERR_NO_ERROR) {
            /* This does not mean an ERROR. The OSP server may not support OSP 2.1.1 */
            LM_DBG("cannot get dest OSP version (%d)\n", errcode);
        } else if (enabled == OSPC_DOSP_FALSE) {
            /* Destination device does not support OSP. Do not send token to it */
            dest->token[0] = '\0';
            dest->tokensize = 0;
        }

        errcode = OSPPTransactionGetDestinationNetworkId(trans, sizeof(dest->dnid), dest->dnid);
        if (errcode != OSPC_ERR_NO_ERROR) {
            /* This does not mean an ERROR. The OSP server may not support OSP 2.1.1 */
            LM_DBG("cannot get dest network ID (%d)\n", errcode);
            dest->dnid[0] = '\0';
        }

        errcode = OSPPTransactionGetCNAM(trans, sizeof(dest->cnam), dest->cnam);
        if (errcode != OSPC_ERR_NO_ERROR) {
            LM_DBG("cannot get CNAM (%d)\n", errcode);
            dest->cnam[0] = '\0';
        }

        OSPPTransactionGetServiceType(trans, &dest->srvtype);

        dest->type = OSPC_ROLE_SOURCE;
        dest->transid = ospGetTransactionId(trans);

        LM_INFO("get destination '%d': "
            "validafter '%s' "
            "validuntil '%s' "
            "timelimit '%d' seconds "
            "callid '%.*s' "
            "calling '%s' "
            "called '%s' "
            "host '%s' "
            "nprn '%s' "
            "npcic '%s' "
            "npdi '%d' "
            /*
            "spid '%s' "
            "ocn '%s' "
            "spn '%s' "
            "altspn '%s' "
            "mcc '%s' "
            "mnc '%s' "
            */
            "cnam '%s' "
            "service '%d' "
            "protocol '%d' "
            "supported '%d' "
            "networkid '%s' "
            "tokensize '%d'\n",
            count,
            dest->validafter,
            dest->validuntil,
            dest->timelimit,
            dest->callidsize,
            dest->callid,
            dest->calling,
            dest->called,
            host,
            dest->nprn,
            dest->npcic,
            dest->npdi,
            /*
            dest->opname[OSPC_OPNAME_SPID],
            dest->opname[OSPC_OPNAME_OCN],
            dest->opname[OSPC_OPNAME_SPN],
            dest->opname[OSPC_OPNAME_ALTSPN],
            dest->opname[OSPC_OPNAME_MCC],
            dest->opname[OSPC_OPNAME_MNC],
            */
            dest->cnam,
            dest->srvtype,
            dest->protocol,
            dest->supported,
            dest->dnid,
            dest->tokensize);
    }

    /*
     * Save destination in reverse order,
     * when we start searching avps the destinations
     * will be in order
     */
    if (result == 0) {
        if (ospSaveInboundInfo(inbound) == -1) {
            ospRecordEvent(0, 500);
            result = -1;
        } else {
            for(count = destcount -1; count >= 0; count--) {
                if (ospSaveOrigDestination(&dests[count]) == -1) {
                    LM_ERR("failed to save originate destination\n");
                    /* Report terminate CDR */
                    ospRecordEvent(0, 500);
                    result = -1;
                    break;
                }
            }
        }
    }

    return result;
}
/*
 * Verify parameters for OSP module
 * return 0 success, -1 failure
 */
static int ospVerifyParameters(void)
{
    int i;
    pv_spec_t avp_spec;
    str avp_str;
    int result = 0;

    if ((_osp_work_mode < 0) || (_osp_work_mode > 1)) {
        _osp_work_mode = OSP_DEF_MODE;
        LM_WARN("work mode is out of range, reset to %d\n", OSP_DEF_MODE);
    }

    if ((_osp_service_type < 0) || (_osp_service_type > 1)) {
        _osp_service_type = OSP_DEF_SERVICE;
        LM_WARN("service type is out of range, reset to %d\n", OSP_DEF_SERVICE);
    }

    /* If use_security_features is 0, ignroe the certificate files */
    if (_osp_use_security != 0) {
        /* Default location for the cert files is in the compile time variable CFG_DIR */
        if (_osp_private_key == NULL) {
            sprintf(_osp_PRIVATE_KEY, "%spkey.pem", CFG_DIR);
            _osp_private_key = _osp_PRIVATE_KEY;
        }

        if (_osp_local_certificate == NULL) {
            sprintf(_osp_LOCAL_CERTIFICATE, "%slocalcert.pem", CFG_DIR);
            _osp_local_certificate = _osp_LOCAL_CERTIFICATE;
        }

        if (_osp_ca_certificate == NULL) {
            sprintf(_osp_CA_CERTIFICATE, "%scacert_0.pem", CFG_DIR);
            _osp_ca_certificate = _osp_CA_CERTIFICATE;
        }
    }

    if (_osp_device_ip != NULL) {
        ospConvertToInAddress(_osp_device_ip, _osp_in_device, sizeof(_osp_in_device));
        ospConvertToOutAddress(_osp_device_ip, _osp_out_device, sizeof(_osp_out_device));
    } else {
        _osp_in_device[0] = '\0';
        _osp_out_device[0] = '\0';
    }

    if (_osp_max_dests > OSP_MAX_DESTS || _osp_max_dests < 1) {
        _osp_max_dests = OSP_DEF_DESTS;
        LM_WARN("max_destinations is out of range, reset to %d\n", OSP_DEF_DESTS);
    }

    if (_osp_report_nid < 0 || _osp_report_nid > 3) {
        _osp_report_nid = OSP_DEF_REPORTNID;
        LM_WARN("report_networkid is out of range, reset to %d\n", OSP_DEF_REPORTNID);
    }

    if (_osp_token_format < 0 || _osp_token_format > 2) {
        _osp_token_format = OSP_DEF_TOKEN;
        LM_WARN("token_format is out of range, reset to %d\n", OSP_DEF_TOKEN);
    }

    _osp_sp_number = 0;
    for (i = 0; i < OSP_DEF_SPS; i++) {
        if (_osp_sp_uris[i] != NULL) {
            if (_osp_sp_number != i) {
                _osp_sp_uris[_osp_sp_number] = _osp_sp_uris[i];
                _osp_sp_weights[_osp_sp_number] = _osp_sp_weights[i];
                _osp_sp_uris[i] = NULL;
                _osp_sp_weights[i] = OSP_DEF_WEIGHT;
            }
            osp_index[_osp_sp_number] = i + 1;
            _osp_sp_number++;
        }
    }

    if (_osp_sp_number == 0) {
        LM_ERR("at least one service point uri must be configured\n");
        result = -1;
    }

    if ((_osp_dnid_location < 0) || (_osp_dnid_location > 3)) {
        _osp_dnid_location = OSP_DEF_DNIDLOC;
        LM_WARN("networkid_location is out of range, reset to %d\n", OSP_DEF_DNIDLOC);
    }

    if (!(_osp_dnid_param && *_osp_dnid_param)) {
        _osp_dnid_param = OSP_DEF_DNIDPARAM;
    }

    if ((_osp_work_mode == 1) && _osp_srcdev_avp && *_osp_srcdev_avp) {
        avp_str.s = _osp_srcdev_avp;
        avp_str.len = strlen(_osp_srcdev_avp);
        if ((pv_parse_spec(&avp_str, &avp_spec) == NULL) ||
            avp_spec.type != PVT_AVP ||
            pv_get_avp_name(0, &(avp_spec.pvp), &_osp_srcdev_avpid, &_osp_srcdev_avptype) != 0)
        {
            LM_WARN("'%s' invalid AVP definition\n", _osp_srcdev_avp);
            _osp_srcdev_avpid = OSP_DEF_AVP;
            _osp_srcdev_avptype = 0;
        }
    } else {
        _osp_srcdev_avpid = OSP_DEF_AVP;
        _osp_srcdev_avptype = 0;
    }

    if (_osp_snid_avp && *_osp_snid_avp) {
        avp_str.s = _osp_snid_avp;
        avp_str.len = strlen(_osp_snid_avp);
        if (pv_parse_spec(&avp_str, &avp_spec) == NULL ||
            avp_spec.type != PVT_AVP ||
            pv_get_avp_name(0, &(avp_spec.pvp), &_osp_snid_avpid, &_osp_snid_avptype) != 0)
        {
            LM_WARN("'%s' invalid AVP definition\n", _osp_snid_avp);
            _osp_snid_avpid = OSP_DEF_AVP;
            _osp_snid_avptype = 0;
        }
    } else {
        _osp_snid_avpid = OSP_DEF_AVP;
        _osp_snid_avptype = 0;
    }

    if (_osp_cinfo_avp && *_osp_cinfo_avp) {
        avp_str.s = _osp_cinfo_avp;
        avp_str.len = strlen(_osp_cinfo_avp);
        if (pv_parse_spec(&avp_str, &avp_spec) == NULL ||
            avp_spec.type != PVT_AVP ||
            pv_get_avp_name(0, &(avp_spec.pvp), &_osp_cinfo_avpid, &_osp_cinfo_avptype) != 0)
        {
            LM_WARN("'%s' invalid AVP definition\n", _osp_cinfo_avp);
            _osp_cinfo_avpid = OSP_DEF_AVP;
            _osp_cinfo_avptype = 0;
        }
    } else {
        _osp_cinfo_avpid = OSP_DEF_AVP;
        _osp_cinfo_avptype = 0;
    }

    ospDumpParameters();

    return result;
}