<commit_before>/*
	Flexisip, a flexible SIP proxy server with media capabilities.
    Copyright (C) 2010  Belledonne Communications SARL.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#include "agent.hh"

#include "etchosts.hh"

using namespace::std;

Transaction::Transaction(sip_t *request){
	su_home_init(&mHome);
	mFrom=sip_from_dup(&mHome,request->sip_from);
	mTo=sip_from_dup(&mHome,request->sip_to);
	mCseq=sip_cseq_dup(&mHome,request->sip_cseq);
	mUser=NULL;
}

Transaction::~Transaction(){
	su_home_deinit (&mHome);
}

void Transaction::setUserPointer(void *up){
	mUser=up;
}

void *Transaction::getUserPointer()const{
	return mUser;
}

static bool from_match(sip_from_t *f1, sip_from_t *f2){
	char a1[128];
	char a2[128];
	sip_from_e(a1,sizeof(a1)-1,(msg_header_t*)f1,0);
	sip_from_e(a2,sizeof(a2)-1,(msg_header_t*)f2,0);
	LOGD("Comparing %s and %s",a1,a2);
	return sip_addr_match(f1,f2)==0;
}

static bool to_match(sip_to_t *f1, sip_to_t *f2){
	char a1[128];
	char a2[128];
	sip_to_e(a1,sizeof(a1)-1,(msg_header_t*)f1,0);
	sip_to_e(a2,sizeof(a2)-1,(msg_header_t*)f2,0);
	LOGD("Comparing %s and %s",a1,a2);
	return sip_addr_match(f1,f2)==0;
}

bool Transaction::matches(sip_t *sip){
	sip_from_t *from=sip->sip_from;
	sip_from_t *to=sip->sip_to;
	sip_cseq_t *cseq=sip->sip_cseq;
	return 
		from_match(mFrom,from) && to_match(mTo,to) 
		&& mCseq->cs_seq==cseq->cs_seq && mCseq->cs_method==cseq->cs_method;
}


Agent::Agent(su_root_t* root, const char *locaddr, int port) : mLocAddr(locaddr), mPort(port){
	char sipuri[128]={0};
	snprintf(sipuri,sizeof(sipuri)-1,"sip:%s:%i;transport=UDP",locaddr,port);
	mAgent=nta_agent_create(root,
		(url_string_t*)sipuri,
			&Agent::messageCallback,
			(nta_agent_magic_t*)this,
			NULL,NULL);
	if (mAgent==NULL){
		LOGE("Could not create sofia mta.");
	}
	EtcHostsResolver::get();
}

Agent::~Agent(){
	if (mAgent)
		nta_agent_destroy(mAgent);
}

void Agent::setDomain(const std::string &domain){
	mDomain=domain;
}

bool Agent::isUs(const url_t *url)const{
	int port=(url->url_port!=NULL) ? atoi(url->url_port) : 5060;
	return strcmp(url->url_host,mLocAddr.c_str())==0
	    && port==mPort;
}

void Agent::addRecordRoute(su_home_t *home, msg_t *msg, sip_t *sip){
	sip_record_route_t *rr=sip_record_route_format(home,"<sip:%s:%i;lr>",mLocAddr.c_str(),mPort);
	if (sip->sip_record_route==NULL){
		sip->sip_record_route=rr;
	}else{
		sip_record_route_t *it;
		for(it=sip->sip_record_route;it->r_next!=NULL;it=it->r_next){
		}
		it->r_next=rr;
	}
}

int Agent::forwardRequest(msg_t *msg, sip_t *sip){
	su_home_t home;
	size_t msg_size;
	char *buf;
	const char *domain;
	url_t* dest=NULL;

	dest=sip->sip_request->rq_url;
	su_home_init(&home);
	switch(sip->sip_request->rq_method){
		case sip_method_invite:
			LOGD("This is an invite");
			break;
		case sip_method_register:
			LOGD("This is a register");
			domain=sip->sip_to->a_url->url_host;
			if (strcasecmp(domain,mDomain.c_str())!=0){
				LOGD("This domain (%s) is not managed by us, forwarding.",domain);
				//rewrite the request uri to the domain
				//this assume the domain is also the proxy
				sip->sip_request->rq_url->url_host=sip->sip_to->a_url->url_host;
				sip->sip_request->rq_url->url_port=sip->sip_to->a_url->url_port;
			}
		case sip_method_ack:
		default:
			break;
	}
	// removes top route header if it maches us
	if (sip->sip_route!=NULL){
		if (isUs(sip->sip_route->r_url)){
			sip_route_remove(msg,sip);
		}else{
			/*forward to this route*/
			dest=sip->sip_route->r_url;
		}
	}
	std::string ip;
	if (EtcHostsResolver::get()->resolve(dest->url_host,&ip)){<commit_msg>fix route processing in case several routes are present<commit_after>/*
	Flexisip, a flexible SIP proxy server with media capabilities.
    Copyright (C) 2010  Belledonne Communications SARL.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#include "agent.hh"

#include "etchosts.hh"

using namespace::std;

Transaction::Transaction(sip_t *request){
	su_home_init(&mHome);
	mFrom=sip_from_dup(&mHome,request->sip_from);
	mTo=sip_from_dup(&mHome,request->sip_to);
	mCseq=sip_cseq_dup(&mHome,request->sip_cseq);
	mUser=NULL;
}

Transaction::~Transaction(){
	su_home_deinit (&mHome);
}

void Transaction::setUserPointer(void *up){
	mUser=up;
}

void *Transaction::getUserPointer()const{
	return mUser;
}

static bool from_match(sip_from_t *f1, sip_from_t *f2){
	char a1[128];
	char a2[128];
	sip_from_e(a1,sizeof(a1)-1,(msg_header_t*)f1,0);
	sip_from_e(a2,sizeof(a2)-1,(msg_header_t*)f2,0);
	LOGD("Comparing %s and %s",a1,a2);
	return sip_addr_match(f1,f2)==0;
}

static bool to_match(sip_to_t *f1, sip_to_t *f2){
	char a1[128];
	char a2[128];
	sip_to_e(a1,sizeof(a1)-1,(msg_header_t*)f1,0);
	sip_to_e(a2,sizeof(a2)-1,(msg_header_t*)f2,0);
	LOGD("Comparing %s and %s",a1,a2);
	return sip_addr_match(f1,f2)==0;
}

bool Transaction::matches(sip_t *sip){
	sip_from_t *from=sip->sip_from;
	sip_from_t *to=sip->sip_to;
	sip_cseq_t *cseq=sip->sip_cseq;
	return 
		from_match(mFrom,from) && to_match(mTo,to) 
		&& mCseq->cs_seq==cseq->cs_seq && mCseq->cs_method==cseq->cs_method;
}


Agent::Agent(su_root_t* root, const char *locaddr, int port) : mLocAddr(locaddr), mPort(port){
	char sipuri[128]={0};
	snprintf(sipuri,sizeof(sipuri)-1,"sip:%s:%i;transport=UDP",locaddr,port);
	mAgent=nta_agent_create(root,
		(url_string_t*)sipuri,
			&Agent::messageCallback,
			(nta_agent_magic_t*)this,
			NULL,NULL);
	if (mAgent==NULL){
		LOGE("Could not create sofia mta.");
	}
	EtcHostsResolver::get();
}

Agent::~Agent(){
	if (mAgent)
		nta_agent_destroy(mAgent);
}

void Agent::setDomain(const std::string &domain){
	mDomain=domain;
}

bool Agent::isUs(const url_t *url)const{
	int port=(url->url_port!=NULL) ? atoi(url->url_port) : 5060;
	return strcmp(url->url_host,mLocAddr.c_str())==0
	    && port==mPort;
}

void Agent::addRecordRoute(su_home_t *home, msg_t *msg, sip_t *sip){
	sip_record_route_t *rr=sip_record_route_format(home,"<sip:%s:%i;lr>",mLocAddr.c_str(),mPort);
	if (sip->sip_record_route==NULL){
		sip->sip_record_route=rr;
	}else{
		sip_record_route_t *it;
		for(it=sip->sip_record_route;it->r_next!=NULL;it=it->r_next){
		}
		it->r_next=rr;
	}
}

int Agent::forwardRequest(msg_t *msg, sip_t *sip){
	su_home_t home;
	size_t msg_size;
	char *buf;
	const char *domain;
	url_t* dest=NULL;

	dest=sip->sip_request->rq_url;
	su_home_init(&home);
	switch(sip->sip_request->rq_method){
		case sip_method_invite:
			LOGD("This is an invite");
			break;
		case sip_method_register:
			LOGD("This is a register");
			domain=sip->sip_to->a_url->url_host;
			if (strcasecmp(domain,mDomain.c_str())!=0){
				LOGD("This domain (%s) is not managed by us, forwarding.",domain);
				//rewrite the request uri to the domain
				//this assume the domain is also the proxy
				sip->sip_request->rq_url->url_host=sip->sip_to->a_url->url_host;
				sip->sip_request->rq_url->url_port=sip->sip_to->a_url->url_port;
			}
		case sip_method_ack:
		default:
			break;
	}
	// removes top route header if it maches us
	if (sip->sip_route!=NULL){
		if (isUs(sip->sip_route->r_url)){
			sip_route_remove(msg,sip);
		}
		if (sip->sip_route!=NULL){
			/*forward to this route*/
			dest=sip->sip_route->r_url;
		}
	}
	std::string ip;
	if (EtcHostsResolver::get()->resolve(dest->url_host,&ip)){
{'fraction_non_alphanumeric': 0.1490011750881316, 'fraction_numerical': 0.015511163337250293, 'mean_word_length': 5.267304860088365, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 98, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4387261', 'n_tokens_mistral': 3642, 'n_tokens_neox': 3464, 'n_words': 692}