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; }
/* * 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); }
/* * 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; }
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; }
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); }
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; }
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); }
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); }