예제 #1
0
static Ret_t prv_start_message_cb(InstanceID_t id,
                                  VoidPtr_t userData,
                                  SmlSyncHdrPtr_t headerP)
{
    internals_t * internP = (internals_t *)userData;
    SmlStatusPtr_t statusP;
    SmlChalPtr_t challengeP = NULL;
    char * dataStr;

    if (internP->reply_ref)
    {
        free(internP->reply_ref);
    }
    internP->sequence = NULL;
    internP->seq_code = 0;

    internP->reply_ref = smlPcdata2String(headerP->msgID);

    if (headerP->cred)
    {
        internP->srv_auth = check_credentials(headerP->cred, internP->account->toClientCred);
        challengeP= get_challenge(internP->account->toClientCred);
        store_nonce(internP->dmtreeH->MOs, internP->account, false);
    }

    dataStr = smlPcdata2String(headerP->respURI);
    if (dataStr)
    {
        set_new_uri(internP, dataStr);
        free(dataStr);
    }

    statusP = create_status(internP, internP->srv_auth, NULL);
    statusP->chal = challengeP;
    add_target_ref(statusP, headerP->target);
    add_source_ref(statusP, headerP->source);

    add_element(internP, (basicElement_t *)statusP);

    return SML_ERR_OK;
}
예제 #2
0
int ds_select_dst_impl(struct sip_msg *msg, char *set_, char *alg_, int set_new)
{
	extern int *ds_activelist;
	extern char ***ds_setp_a, ***ds_setp_b;
	extern int *ds_setlen_a, *ds_setlen_b;

	int set, alg;
	unsigned int hash;

	str uri;

	if(msg==NULL)
    {
        LOG(L_ERR, "DISPATCHER:ds_select_dst: bad parameters\n");
        return -1;
    }

	if ( get_int_fparam(&set, msg, (fparam_t*)set_) < 0 ) {
	  LOG(L_ERR, "DISPATCHER:ds_select_dst: bad set value (%d)\n", set);
	  return -1;
	}

	if ( get_int_fparam(&alg, msg, (fparam_t*)alg_) < 0 ) {
	  LOG(L_ERR, "DISPATCHER:ds_select_dst: bad algorithm (%d)\n", alg);
	  return -1;
	}

    if ((set < 0) || (set >= DS_MAX_SETS)) {
        LOG(L_ERR, "DISPATCHER:ds_select_dst: bad set offset (%d)\n", set);
        return -1;
    }
    if ((alg < 0) || (alg > 4)) {
        LOG(L_ERR, "DISPATCHER:ds_select_dst: invalid algorithm\n");
        return -1;
    }

	if (((*ds_activelist == 0) ?  ds_setlen_a[set] : ds_setlen_b[set]) <= 0) {
        LOG(L_ERR, "DISPATCHER:ds_select_dst: empty destination set\n");
        return -1;
    }
    if (msg->dst_uri.s != NULL || msg->dst_uri.len > 0) {
		if (msg->dst_uri.s)
            pkg_free(msg->dst_uri.s);
        msg->dst_uri.s = NULL;
        msg->dst_uri.len = 0;
    }
    /* get hash */
    hash = 0;
    switch (alg) {
		/* see bottom for case '0' */
        case 1: /* hash from uri */
            if (ds_hash_fromuri(msg, &hash) != 0) {
                if (ds_hash_callid(msg, &hash) != 0) {
                    LOG(L_ERR, "DISPATCHER:ds_select_dst: cannot determine from uri hash\n");
                    return -1;
                }
            }
            break;
        case 2: /* hash to uri */
            if (ds_hash_touri(msg, &hash) != 0) {
                if (ds_hash_callid(msg, &hash) != 0) {
                    LOG(L_ERR, "DISPATCHER:ds_select_dst: cannot determine from uri hash\n");
                    return -1;
                }
            }
            break;
        case 3: /* hash Request uri */
            if (ds_hash_ruri(msg, &hash) != 0) {
                if (ds_hash_callid(msg, &hash) != 0) {
                    LOG(L_ERR, "DISPATCHER:ds_select_dst: cannot determine from uri hash\n");
                    return -1;
                }
            }
            break;
		case 4:	/* Call ID hash, shifted right once to skip low bit
				 * This should allow for even distribution when using
				 * Call ID hash twice (i.e. fe + be)
				 */
            if (ds_hash_callid(msg, &hash) != 0) {
                LOG(L_ERR,
                    "DISPATCHER:ds_select_dst: cannot determine callid hash\n");
                hash = 0; /* bad default, just to be sure */
                return -1;
            }
			hash = hash >> 4; /* should be enough for even more backends */
			break;
        case 0: /* hash call id */ /* fall-through */
        default:
            if (ds_hash_callid(msg, &hash) != 0) {
                LOG(L_ERR,
                    "DISPATCHER:ds_select_dst: cannot determine callid hash\n");
                hash = 0; /* bad default, just to be sure */
                return -1;
            }
			break; /* make gcc happy */
    }

    DBG("DISPATCHER:ds_select_dst: hash: [%u]\n", hash);
    /* node list offset from hash */
    if (*ds_activelist == 0) {
        hash = hash % ds_setlen_a[set];
        uri.s = ds_setp_a[set][hash];
        uri.len = strlen(ds_setp_a[set][hash]);
    } else {
        hash = hash % ds_setlen_b[set];
        uri.s = ds_setp_b[set][hash];
        uri.len = strlen(ds_setp_b[set][hash]);
    }

	if (!set_new) {
		if (set_dst_uri(msg, &uri) < 0) {
            LOG(L_ERR,
				"DISPATCHER:dst_select_dst: Error while setting dst_uri\n");
            return -1;
        }
		/* dst_uri changed, so it makes sense to re-use the current uri for
			forking */
		ruri_mark_new(); /* re-use uri for serial forking */
    	DBG("DISPATCHER:ds_select_dst: selected [%d-%d-%d] <%.*s>\n",
        	alg, set, hash, msg->dst_uri.len, msg->dst_uri.s);
	} else {
		if (set_new_uri(msg, &uri) < 0) {
            LOG(L_ERR,
				"DISPATCHER:dst_select_dst: Error while setting new_uri\n");
            return -1;
        }
    	DBG("DISPATCHER:ds_select_dst: selected [%d-%d-%d] <%.*s>\n",
        	alg, set, hash, msg->new_uri.len, msg->dst_uri.s);
    }

    return 1;
}
예제 #3
0
int ds_select_dst_impl(struct sip_msg *msg, char *set, char *alg, int set_new)
{
	int a, s, idx;
	ds_setidx_p si = NULL;
	unsigned int hash;

	if(msg==NULL)
	{
		LOG(L_ERR, "DISPATCHER:ds_select_dst: bad parameters\n");
		return -1;
	}
	
	if(_ds_list==NULL || _ds_index==NULL)
	{
		LOG(L_ERR, "DISPATCHER:ds_select_dst: no destination sets\n");
		return -1;
	}

	if((force_dst==0) && (msg->dst_uri.s!=NULL || msg->dst_uri.len>0))
	{
		LOG(L_ERR,
			"DISPATCHER:ds_select_dst: destination already set [%.*s]\n",
			msg->dst_uri.len, msg->dst_uri.s);
		return -1;
	}
	
	get_int_fparam(&s, msg, (fparam_t*)set);
	get_int_fparam(&a, msg, (fparam_t*)alg);

	/* get the index of the set */
	si = _ds_index;
	while(si)
	{
		if(si->id == s)
		{
			idx = si->index;
			break;
		}
		si = si->next;
	}

	if(si==NULL)
	{
		LOG(L_ERR,
			"DISPATCHER:ds_select_dst: destination set [%d] not found\n",s);
		return -1;
	}

	DBG("DISPATCHER:ds_select_dst: set index [%d]\n", idx);

	hash = 0;
	switch(a)
	{
		case 0:
			if(ds_hash_callid(msg, &hash)!=0)
			{
				LOG(L_ERR,
					"DISPATCHER:ds_select_dst: can't get callid hash\n");
				return -1;
			}
		break;
		case 1:
			if(ds_hash_fromuri(msg, &hash)!=0)
			{
				LOG(L_ERR,
					"DISPATCHER:ds_select_dst: can't get From uri hash\n");
				return -1;
			}
		break;
		case 2:
			if(ds_hash_touri(msg, &hash)!=0)
			{
				LOG(L_ERR,
					"DISPATCHER:ds_select_dst: can't get To uri hash\n");
				return -1;
			}
		break;
		case 3:
			if (ds_hash_ruri(msg, &hash)!=0)
			{
				LOG(L_ERR,	
					"DISPATCHER:ds_select_dst: can't get ruri hash\n");
				return -1;
			}
		break;
		default:
			LOG(L_WARN,
					"WARNING: ds_select_dst: algo %d not implemented"
					" using callid hashing instead...\n", a);
			hash = 0;
	}

	DBG("DISPATCHER:ds_select_dst: alg hash [%u]\n", hash);

	hash = hash%_ds_list[idx].nr;

	if (!set_new) {
		if (set_dst_uri(msg, &_ds_list[idx].dlist[hash].uri) < 0) {
			LOG(L_ERR, "DISPATCHER:dst_select_dst: Error while setting dst_uri\n");
			return -1;
		}

		DBG("DISPATCHER:ds_select_dst: selected [%d-%d/%d/%d] <%.*s>\n",
				a, s, idx, hash, msg->dst_uri.len, msg->dst_uri.s);
	}
	else {
		if (set_new_uri(msg, &_ds_list[idx].dlist[hash].uri) < 0) {
			LOG(L_ERR, "DISPATCHER:dst_select_dst: Error while setting new_uri\n");
			return -1;
		}
		DBG("DISPATCHER:ds_select_new: selected [%d-%d/%d/%d] <%.*s>\n",
				a, s, idx, hash, msg->new_uri.len, msg->new_uri.s);
	}
	
	return 1;
}