示例#1
0
struct addrinfo *_belle_sip_alloc_addrinfo(int ai_family, int socktype, int proto){
	struct addrinfo *ai=(struct addrinfo*)belle_sip_malloc0(sizeof(struct addrinfo));
	ai->ai_family=ai_family;
	ai->ai_socktype=socktype;
	ai->ai_protocol=proto;
	ai->ai_addrlen=AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
	ai->ai_addr=(struct sockaddr *) belle_sip_malloc0(ai->ai_addrlen);
	return ai;
}
示例#2
0
/*
 * this function is to avoid logging too much or non-ascii data received.
 */
static char *make_logbuf(belle_sip_log_level level, const char *buffer, size_t size){
	char *logbuf;
	char truncate_msg[128]={0};
	int limit=3000;
	size_t non_ascii_pos;
	
	if (!belle_sip_log_level_enabled(level)){
		return belle_sip_malloc0(1);
	}
	non_ascii_pos=find_non_asci(buffer,MIN(size,limit));
	if (non_ascii_pos<2){
		limit=0;
		snprintf(truncate_msg,sizeof(truncate_msg)-1,"... (binary data)");
	}else limit=non_ascii_pos;
	if (limit!=0 && size>limit){
		snprintf(truncate_msg,sizeof(truncate_msg)-1," ... (first %i bytes shown)",limit);
		size=limit;
	}
	if (size<limit)
		limit=size;
	if (truncate_msg[0]!=0){
		size+=sizeof(truncate_msg);
	}
	logbuf=belle_sip_malloc(size+1);
	strncpy(logbuf,buffer,limit);
	if (truncate_msg[0]!=0){
		strncpy(logbuf+limit,truncate_msg,sizeof(truncate_msg));
	}
	logbuf[size]='\0';
	return logbuf;
}
static belle_sip_error_code checked_marshal(belle_sip_object_vptr_t *vptr, belle_sip_object_t* obj, char* buff, size_t buff_size, size_t *offset){
	size_t tmp_buf_size=buff_size*2;
	char *p=(char*)belle_sip_malloc0(tmp_buf_size);
	size_t i;
	size_t initial_offset=*offset;
	belle_sip_error_code error=vptr->marshal(obj,p,buff_size,offset);
	size_t written;

	for (i=initial_offset;i<buff_size;++i){
		if (p[i]=='\0') break;
	}
	written=i-initial_offset;
	if (error==BELLE_SIP_BUFFER_OVERFLOW){
		belle_sip_error("Object of type %s commited a buffer overflow by marshalling %i bytes",
			vptr->type_name,(int)(*offset-initial_offset));
	} else if (error!=BELLE_SIP_OK){
		belle_sip_error("Object of type %s produced an error during marshalling: %i",
			vptr->type_name,error);
	}
	if (written!=(*offset-initial_offset) && written!=(buff_size-initial_offset-1)){ /*this is because snprintf won't allow you to write a non null character at the end of the buffer*/
		belle_sip_fatal("Object of type %s marshalled %i bytes but said it marshalled %i bytes !",
			vptr->type_name,(int)written,(int)(*offset-initial_offset));
	}
	memcpy(buff+initial_offset,p+initial_offset,*offset-initial_offset);
	belle_sip_free(p);
	return error;
}
int belle_sip_object_data_set( belle_sip_object_t *obj, const char* name, void* data, belle_sip_data_destroy destroy_func )
{
	int ret = 0;
	struct _belle_sip_list*  list_entry = belle_sip_list_find_custom(obj->data_store, belle_sip_object_data_find, name);
	struct belle_sip_object_data* entry = (list_entry)? list_entry->data : NULL;

	if( entry == NULL){
		entry = belle_sip_malloc0(sizeof( struct belle_sip_object_data));
		obj->data_store = belle_sip_list_append(obj->data_store, entry);
	}
	else {
		// clean previous data
		if( entry->destroy_func ) entry->destroy_func(entry->data);
		belle_sip_free(entry->name);
		ret = 1;
	}

	if( entry ){
		entry->data = data;
		entry->name = belle_sip_strdup(name);
		entry->destroy_func = destroy_func;
	} else {
		ret = -1;
	}
	return ret;
}
static void test_overflow(void){
	belle_sdp_session_description_t* sdp;
	belle_sip_list_t *mds;
	belle_sdp_media_description_t *vmd;
	int i;
	const size_t orig_buffsize=1024;
	size_t buffsize=orig_buffsize;
	char *buffer=belle_sip_malloc0(buffsize);
	size_t offset=0;
	
	sdp=belle_sdp_session_description_parse(big_sdp);
	CU_ASSERT_PTR_NOT_NULL(sdp);
	mds=belle_sdp_session_description_get_media_descriptions(sdp);
	CU_ASSERT_PTR_NOT_NULL(mds);
	CU_ASSERT_PTR_NOT_NULL(mds->next);
	vmd=(belle_sdp_media_description_t*)mds->next->data;
	for(i=0;i<16;i++){
		belle_sdp_media_description_add_attribute(vmd,belle_sdp_attribute_create("candidate","2 1 UDP 1694498815 82.65.223.97 9078 typ srflx raddr 192.168.0.2 rport 9078"));
	}

	CU_ASSERT_EQUAL(belle_sip_object_marshal(BELLE_SIP_OBJECT(sdp),buffer,buffsize,&offset),BELLE_SIP_BUFFER_OVERFLOW);
	belle_sip_message("marshal size is %i",(int)offset);
	CU_ASSERT_TRUE(offset==buffsize);
	belle_sip_object_unref(sdp);
	belle_sip_free(buffer);
}
示例#6
0
/*
 * this function is to avoid logging too much or non-ascii data received.
 */
static char *make_logbuf(belle_sip_log_level level, const char *buffer, size_t size){
	char *logbuf;
	char truncate_msg[128]={0};
	int limit=7000; /*big message when many ice candidates*/

	if (!belle_sip_log_level_enabled(level)){
		return belle_sip_malloc0(1);
	}
	limit=find_non_printable(buffer,MIN(size,limit));
	if (limit==0){
		snprintf(truncate_msg,sizeof(truncate_msg)-1,"... (binary data)");
	} else if (size>limit){
		snprintf(truncate_msg,sizeof(truncate_msg)-1,"... (first %i bytes shown)",limit);
		size=limit;
	}

	if (truncate_msg[0]!=0){
		size+=sizeof(truncate_msg);
	}

	logbuf=belle_sip_malloc(size+1);
	strncpy(logbuf,buffer,limit);
	if (truncate_msg[0]!=0){
		strncpy(logbuf+limit,truncate_msg,sizeof(truncate_msg));
	}
	logbuf[size]='\0';
	return logbuf;
}
示例#7
0
static void __belle_sip_logv_out(belle_sip_log_level lev, const char *fmt, va_list args){
	const char *lname="undef";
	char *msg;
	struct timeval tp;
	struct tm *lt;
#ifndef _WIN32
	struct tm tmstorage;
#endif
	time_t curtime;

	belle_sip_gettimeofday(&tp,NULL);
	curtime=tp.tv_sec;
#ifdef _WIN32
	lt = localtime(&curtime);
#else
	lt = localtime_r(&curtime,&tmstorage);
#endif

	if (__log_file==NULL) __log_file=stderr;
	switch(lev){
		case BELLE_SIP_LOG_DEBUG:
			lname="debug";
			break;
		case BELLE_SIP_LOG_MESSAGE:
			lname="message";
			break;
		case BELLE_SIP_LOG_WARNING:
			lname="warning";
			break;
		case BELLE_SIP_LOG_ERROR:
			lname="error";
			break;
		case BELLE_SIP_LOG_FATAL:
			lname="fatal";
			break;
		default:
			belle_sip_fatal("Bad level !");
	}
	msg=belle_sip_strdup_vprintf(fmt,args);
#if defined(_MSC_VER) && !defined(_WIN32_WCE)
	#ifndef _UNICODE
	OutputDebugStringA(msg);
	OutputDebugStringA("\r\n");
	#else
	{
		int len=strlen(msg);
		wchar_t *tmp=(wchar_t*)belle_sip_malloc0((len+1)*sizeof(wchar_t));
		mbstowcs(tmp,msg,len);
		OutputDebugStringW(tmp);
		OutputDebugStringW(L"\r\n");
		belle_sip_free(tmp);
	}
	#endif
#endif
	fprintf(__log_file,"%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i belle-sip-%s-%s" ENDLINE,1900+lt->tm_year,lt->tm_mon+1,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_sec,(int)(tp.tv_usec/1000), lname,msg);
	fflush(__log_file);
	free(msg);
}
belle_sip_object_t * _belle_sip_object_new(size_t objsize, belle_sip_object_vptr_t *vptr){
	belle_sip_object_t *obj=(belle_sip_object_t *)belle_sip_malloc0(objsize);
	obj->ref=vptr->initially_unowned ? 0 : 1;
	obj->vptr=vptr;
	obj->size=objsize;
	if (obj->ref==0){
		belle_sip_object_pool_t *pool=belle_sip_object_pool_get_current();
		if (pool) belle_sip_object_pool_add(pool,obj);
	}
	return obj;
}
belle_sip_object_t *belle_sip_object_clone(const belle_sip_object_t *obj){
	belle_sip_object_t *newobj;

	newobj=belle_sip_malloc0(obj->vptr->size);
	newobj->ref=obj->vptr->initially_unowned ? 0 : 1;
	newobj->vptr=obj->vptr;
	_belle_sip_object_copy(newobj,obj);
	if (newobj->ref==0){
		belle_sip_object_pool_t *pool=belle_sip_object_pool_get_current();
		if (pool) belle_sip_object_pool_add(pool,newobj);
	}
	add_new_object(newobj);
	return newobj;
}
示例#10
0
int main(int argc, char *argv[]){
	char *str;
	struct stat st;
	int fd;
	int i;
	
	if (argc!=2){
		fprintf(stderr,"Usage:\n%s <text file containing messages>\n",argv[0]);
		return -1;
	}
	if (stat(argv[1],&st)==-1){
		fprintf(stderr,"Could not stat %s: %s\n",argv[1],strerror(errno));
		return -1;
	}
	
	fd=open(argv[1],O_RDONLY);
	if (fd==-1){
		fprintf(stderr,"Could not open %s: %s\n",argv[1],strerror(errno));
		return -1;
	}
	str=belle_sip_malloc0(st.st_size+1);
	if (read(fd,str,st.st_size)==-1){
		fprintf(stderr,"Could not open %s: %s\n",argv[1],strerror(errno));
		belle_sip_free(str);
		close(fd);
		return -1;
	}
	close(fd);
	
	for (i=0;i<st.st_size;){
		size_t read;
		belle_sip_message_t *msg=belle_sip_message_parse_raw(str+i,st.st_size-i,&read);
		if (msg){
			printf("Succesfully parsed message of %i bytes.",(int)read);
		}else{
			fprintf(stderr,"Failed to parse message.");
			break;
		}
		i+=read;
	}
	belle_sip_free(str);
	return 0;
}
void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
	size_t pfd_size = ml->nsources * sizeof(belle_sip_pollfd_t);
	belle_sip_pollfd_t *pfd=(belle_sip_pollfd_t*)belle_sip_malloc0(pfd_size);
	int i=0;
	belle_sip_source_t *s;
	belle_sip_list_t *elem,*next;
	uint64_t min_time_ms=(uint64_t)-1;
	int duration=-1;
	int ret;
	uint64_t cur;
	belle_sip_list_t *to_be_notified=NULL;
	int can_clean=belle_sip_object_pool_cleanable(ml->pool); /*iterate might not be called by the thread that created the main loop*/ 
	belle_sip_object_pool_t *tmp_pool=NULL;
	
	if (!can_clean){
		/*Push a temporary pool for the time of the iterate loop*/
		tmp_pool=belle_sip_object_pool_push();
	}
	
	/*Step 1: prepare the pollfd table and get the next timeout value */
	for(elem=ml->sources;elem!=NULL;elem=next){
		next=elem->next;
		s=(belle_sip_source_t*)elem->data;
		if (!s->cancelled){
			if (s->fd!=(belle_sip_fd_t)-1){
				belle_sip_source_to_poll(s,pfd,i);
				++i;
			}
			if (s->timeout>=0){
				if (min_time_ms>s->expire_ms){
					min_time_ms=s->expire_ms;
				}
			}
		}
	}
	
	if (min_time_ms!=(uint64_t)-1 ){
		int64_t diff;
		/* compute the amount of time to wait for shortest timeout*/
		cur=belle_sip_time_ms();
		diff=min_time_ms-cur;
		if (diff>0)
			duration=(int)diff;
		else 
			duration=0;
	}
	/* do the poll */
	ret=belle_sip_poll(pfd,i,duration);
	if (ret==-1){
		goto end;
	}
	
	/* Step 2: examine poll results and determine the list of source to be notified */
	cur=belle_sip_time_ms();
	for(elem=ml->sources;elem!=NULL;elem=elem->next){
		unsigned revents=0;
		s=(belle_sip_source_t*)elem->data;

		if (!s->cancelled){
			if (s->fd!=(belle_sip_fd_t)-1){
				if (s->notify_required) { /*for testing purpose to force channel to read*/
					revents=BELLE_SIP_EVENT_READ;
					s->notify_required=0; /*reset*/
				} else {
					revents=belle_sip_source_get_revents(s,pfd);
				}
				s->revents=revents;
			}
			if (revents!=0 || (s->timeout>=0 && cur>=s->expire_ms)){
				to_be_notified=belle_sip_list_append(to_be_notified,belle_sip_object_ref(s));
				s->expired=TRUE;
				if (s->revents==0)
					s->revents=BELLE_SIP_EVENT_TIMEOUT;
			}
		}else to_be_notified=belle_sip_list_append(to_be_notified,belle_sip_object_ref(s));
	}
	
	/* Step 3: notify those to be notified */
	for(elem=to_be_notified;elem!=NULL;){
		s=(belle_sip_source_t*)elem->data;
		next=elem->next;
		if (!s->cancelled){
			char *objdesc=belle_sip_object_to_string((belle_sip_object_t*)s);
			if (s->timeout>0)/*to avoid too many traces*/ belle_sip_debug("source %s notified revents=%u, timeout=%i",objdesc,revents,s->timeout);
			belle_sip_free(objdesc);
			ret=s->notify(s->data,s->revents);
			if (ret==BELLE_SIP_STOP || s->oneshot){
				/*this source needs to be removed*/
				belle_sip_main_loop_remove_source(ml,s);
			}else if (s->revents==BELLE_SIP_EVENT_TIMEOUT){
				/*timeout needs to be started again */
				s->expire_ms+=s->timeout;
				s->expired=FALSE;
			}
		}else belle_sip_main_loop_remove_source(ml,s);
		belle_sip_object_unref(s);
		belle_sip_free(elem); /*free just the element*/
		elem=next;
	}
	
	if (can_clean) belle_sip_object_pool_clean(ml->pool);
	else if (tmp_pool) belle_sip_object_unref(tmp_pool);
end:
	belle_sip_free(pfd);
}
示例#12
0
int main(int argc, char *argv[]){
	char *str;
	struct stat st;
	int fd;
	int i;
	const char *filename=NULL;
	const char *protocol="sip";

	if (argc<2){
		fprintf(stderr,"Usage:\n%s [--protocol sip|http|sdp] <text file containing messages>\n",argv[0]);
		return -1;
	}
	for(i=1;i<argc;++i){
		if (strcmp(argv[i],"--protocol")==0){
			i++;
			if (i<argc){
				protocol=argv[i];
			}else{
				fprintf(stderr,"Missing argument for --protocol\n");
				return -1;
			}
		}else filename=argv[i];
	}
	if (!filename){
		fprintf(stderr,"No filename specified\n");
				return -1;
	}
	if (stat(filename,&st)==-1){
		fprintf(stderr,"Could not stat %s: %s\n",filename,strerror(errno));
		return -1;
	}

	fd=open(filename,O_RDONLY);
	if (fd==-1){
		fprintf(stderr,"Could not open %s: %s\n",filename,strerror(errno));
		return -1;
	}
	str=belle_sip_malloc0(st.st_size+1);
	if (read(fd,str,st.st_size)==-1){
		fprintf(stderr,"Could not read %s: %s\n",filename,strerror(errno));
		belle_sip_free(str);
		close(fd);
		return -1;
	}
	close(fd);
	belle_sip_set_log_level(BELLE_SIP_LOG_DEBUG);

	for (i=0;i<st.st_size;){
		size_t read;
		if (strcasecmp(protocol,"sip")==0 || strcasecmp(protocol,"http")==0){
			belle_sip_message_t *msg;
			uint64_t begin,end;
			begin=belle_sip_time_ms();
			msg=belle_sip_message_parse_raw(str+i,st.st_size-i,&read);
			end=belle_sip_time_ms();
			if (msg){
				printf("Successfully parsed %s message of %i bytes in %i ms.\n",protocol,(int)read, (int)(end-begin));
			}else{
				fprintf(stderr,"Failed to parse message.\n");
				break;
			}
			i+=read;
		}else if (strcasecmp(protocol,"sdp")==0){
			belle_sdp_session_description_t *sdp=belle_sdp_session_description_parse(str);
			if (sdp){
				printf("Successfully parsed %s message of %i bytes.\n",protocol,(int)strlen(str));
			}else{
				fprintf(stderr,"Failed to parse SDP message.\n");
			}
			break;
		}
	}
	belle_sip_free(str);
	return 0;
}
示例#13
0
static void _linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value) {
    LinphoneXmlRpcArg *arg = belle_sip_malloc0(sizeof(LinphoneXmlRpcArg));
    arg->type = LinphoneXmlRpcArgString;
    arg->data.s = belle_sip_strdup(value);
    request->arg_list = belle_sip_list_append(request->arg_list, arg);
}
示例#14
0
static void _linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value) {
    LinphoneXmlRpcArg *arg = belle_sip_malloc0(sizeof(LinphoneXmlRpcArg));
    arg->type = LinphoneXmlRpcArgInt;
    arg->data.i = value;
    request->arg_list = belle_sip_list_append(request->arg_list, arg);
}