📄 sipd.c
字号:
/***********************************************************************\ SIP Server Date Ver Author MemoRandom Jul 3,2002 1.0 Hiroaki Hata Created Apr 3,2003 1.1 Hiroaki Hata Transfer module Jul 7,2003 1.2 Hiroaki Hata Bug Fix Sep24,2003 1.3 Hiroaki Hata BugFix,WMessenger5 (C) 2002 All Copyrights reserved. *************************************************************************/#include <sys/types.h>#include <stdio.h>#include <time.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <error.h>#include <errno.h>#include <signal.h>#include <string.h>#include <unistd.h>#include "udp.h"#include "sipd.h"#include "parser.h"#define CONF "sipd.conf"extern int dump_flag;int debug=0;char proxy_server[CLEN];char domain[DOMAIN_MAX][CLEN];char HOSTID[CLEN];short HOSTPORT;#define VER "oni sip server ver 1.2 build #2003092402"static void init_application(char *);#ifdef EMULATIONint emulation=1;static int RecvData_emu(int sock,char *rbuff,int *rlen,int *caddr, int *cport,int timeout,int *ret);static void display_message(MESSAGE *mes);#elseint emulation=0;#endifint f_spec=1;void syserr(char *mes){ char bf[128]; if(errno == EINTR) return; if(strlen(mes)>80) mes[80]='\0'; sprintf(bf,"ERROR: %s %d",mes,errno); logging(3,bf); logging(3," ;None System Error Message"); exit(1);}static void init_application(char *filename){ FILE *fp; char tag[80]; char value[80]; char buff[80]; int i; int n; int h=0; HOSTPORT=SIP_PORT; proxy_server[0]='\0'; for(i=0;i<DOMAIN_MAX;i++){ domain[i][0]='\0'; } fp=fopen(filename,"r"); if(fp==NULL){ logging(3,"conf file error"); exit(1); } for(i=0;;){ if(NULL==fgets(buff,80,fp)){ break; } if(*buff=='#'||*buff=='\0'||*buff=='\n'){ continue; } n=sscanf(buff,"%s %s",tag,value); if(strcmp("DOMAIN",tag)==0){ if(strlen(value)<=0 || strlen(value) >80){ logging(3,"Conf:String length too long(DOMAIN)"); exit(1); } strcpy(domain[i++],value); }else if(strcmp("PROXY",tag)==0){ if(strlen(value)<=0 || strlen(value) >80){ logging(3,"Conf:String length too long(PROXY)"); exit(1); } strcpy(proxy_server,value); }else if(strcmp("HOSTID",tag)==0){ if(strlen(value)<=0 || strlen(value) >80){ logging(3,"Conf:String length too long(HOSTID)"); exit(1); } strcpy(HOSTID,value); h=1; }else if(strcmp("HOSTPORT",tag)==0){ if(strlen(value)<=0 || strlen(value) >80){ logging(3,"Conf:String length too long(HOSTPORT)\n"); exit(1); } HOSTPORT=atoi(value); } } if(HOSTPORT==0){ HOSTPORT=SIP_PORT; } if(i==0){ logging(3,"Init:Domain not specified\n"); exit(1); } if(h==0){ logging(3,"Init:Host not specified\n"); exit(1); }}static int ProcessRequest(MESSAGE *mes){ int ret; switch(mes->start.message){ case M_REGISTER: ret=Register(mes); break; case M_SUBSCRIBE: ret=Subscribe(mes); break; case M_BYE: case M_INVITE: case M_ACK: case M_CANCEL: case M_MESSAGE: ret=Transfer(mes); break; default: ret=415; } return ret;}static int ProcessResponse(MESSAGE *mes){////レスポンスを减慨した眷圭、VIAヘッダを浮瑚して啪流黎を疯年する。//VIAチェ〖ンの呵稿萨に极サ〖バのアドレスが呈羌されていれば、//极サ〖バ案とみなし啪流をかけない。VIAチェ〖ンの呵稿萨が极尸でなければ//啪流する。啪流黎は、VIAチェ〖ンの黎片である.////// VIA *v; int ret; unsigned char hash[HASH_LEN]; CONTAINER data; memset(hash,0,HASH_LEN); if(mes->start.code == E_UNAUTH || mes->start.code == E_PROXYAUTH){ //コ〖ドが407もしくは401ならハッシュを纷换し //略ちプロセスを浮瑚する //あれば、パイプに流り哈む。なければ茄逮 memset(&data,0,sizeof(CONTAINER)); //エラ〖を袋略するINVITEのCSEQはデクリメントされているため //エラ〖のCSEQもデクリメントされたものが手されている mes->header.cseq.seq++; ret=CalcHash(mes,hash); if(ret!=OK){ logging(3,"Calc Hash Failed"); return NG; } memcpy(&data.to,&mes->header.to,sizeof(URI)); memcpy(&data.auth,mes->header.authtc,sizeof(PAUTH)); ret=SendCoProcess(&data, mes->header.to.username,hash); if(ret!=OK){ logging(2,"Waiting Response Not found"); } }else{ //Viaをみて啪流する v=mes->header.via; if(v==NULL){ logging(2,"No VIA in this Response"); logging(2,mes->start.response); ret=NG; } for(;v->next!=NULL;v=v->next){} // //办戎のVIAが极尸でなれば、啪流する // if(strcmp(HOSTID, v->host)==0){ logging(0,"Received Response"); logging(0,mes->start.response); logging(0,mes->ip); ret=OK; }else{ ret=Transfer(mes); } } return ret ;}static void LoopProcess(){ char rbuff[MAX_BUFF]; char *copybuff; char ip[32]; int rlen; int i,n; int caddr; int cport; int ret; int s; MESSAGE *mes; s=InitializeUDP(SIP_PORT); logging(1,VER); logging(1,"sipd starts----------------------"); for(i=0;;i++){ //----------------------------------------Recv DataGram rlen=MAX_BUFF; mes=(MESSAGE*)malloc(sizeof(MESSAGE)); if(mes==NULL){break;} memset(mes,0,sizeof(MESSAGE)); mes->header.expires=-1; mes->header.maxforwards=-1;#ifdef EMULATION n=RecvData_emu(s,rbuff,&rlen,&caddr,&cport,DB_WATCH,&ret);#else n=RecvData(s,rbuff,&rlen,&caddr,&cport,DB_WATCH,&ret);#endif if(n<=0){ if(ret==RECV_TIME_OUT){ CheckProcess(); continue; }else{ syserr("RecvData:"); exit(0); } } rbuff[n]='\0'; /*IPアドレスを艰评*/ ConvertIP4(caddr,ip); strcpy(mes->ip,ip); mes->port=cport; copybuff=(char *)malloc(rlen+1); if(copybuff==NULL){ logging(3,"recv buffer memory short ...101"); continue; } mes->buff=copybuff; mes->len=rlen; memcpy(copybuff,rbuff,rlen); copybuff[rlen]='\0'; //Analyze DataGram ret=AnalyzePDU(rbuff,rlen,mes); if(ret==OK){ /******************************/DEBUG // display_message(mes);DEND /******************************/ if(mes->start.type==REQUEST){ ret=ProcessRequest(mes); }else{ ret=ProcessResponse(mes); } }else{ logging(1,"AnalyzePDU Error"); } free_message_buffer(mes); mes=NULL;DEBUG fflush(stdout);DEND CheckProcess(); if(emulation==1) { sleep(2); } }}#ifdef EMULATIONstatic void display_message(MESSAGE *mes){ VIA *v; URI *s; char bf[128]; int level=9; if(emulation==1) level=0; sprintf(bf,"----------------------------------");logging(level,bf); sprintf(bf,"position:%X",(int)mes);logging(level,bf); sprintf(bf,"START.type:%d",mes->start.type);logging(level,bf); sprintf(bf,"START.message:%d",mes->start.message);logging(level,bf); sprintf(bf,"START.method:%s",mes->start.method);logging(level,bf); sprintf(bf,"START.REQ-URI(host):%s\n",mes->start.requri.host); sprintf(bf,"START.proto:%s",mes->start.proto);logging(level,bf); sprintf(bf,"START.code:%d",mes->start.code);logging(level,bf); //------------ logging(level,"From-----------------------------"); DisplayURI(level,&mes->header.from); logging(level,"To-----------------------------"); DisplayURI(level,&mes->header.to); for(s=mes->header.contact;s!=NULL;s=s->next){ logging(level,"Contact-----------------------------"); DisplayURI(level,s); } for(s=mes->header.route;s!=NULL;s=s->next){ logging(level,"Route-----------------------------"); DisplayURI(level,s); } for(s=mes->header.recordroute;s!=NULL;s=s->next){ logging(level,"Route-Record-----------------------------"); DisplayURI(level,s); } for(v=mes->header.via;v!=NULL;v=v->next){; sprintf(bf,"Via=%X",(int)v);logging(level,bf); sprintf(bf,"Via.proto:%s",v->proto);logging(level,bf); sprintf(bf,"Via.ver:%s",v->ver);logging(level,bf); sprintf(bf,"Via.trans:%s",v->trans);logging(level,bf); sprintf(bf,"Via.host:%s",v->host);logging(level,bf); sprintf(bf,"Via.port:%d",v->port);logging(level,bf); sprintf(bf,"Via.param.branch:%s",v->param.branch); logging(level,bf); } sprintf(bf,"CSeq.seq:%d",mes->header.cseq.seq);logging(level,bf); sprintf(bf,"CSeq.met:%s",mes->header.cseq.method);logging(level,bf); sprintf(bf,"Call-id:%s",mes->header.callid);logging(level,bf); printf("Proxy-Authenticate-----------------\n"); DisplayPAUTH(mes->header.authtc); printf("Proxy-Authorization-----------------\n"); DisplayPAUTH(mes->header.authrz);}#endifint main(int argc,char **argv){ char filename[128]; time_t t; int ret; debug=1; time(&t); srand(t); strcpy(filename,CONF); init_application(filename); InitHosts(filename); InitProcess(); ret=InitDB(); if(ret!=OK){ logging(1,"Initialize DB NG"); return -1; } LoopProcess(); return 0;}/************************/#ifdef EMULATIONstatic int RecvData_emu(int sock,char *rbuff,int *rlen, int *caddr, int *cport,int timeout,int *ret){ char buff[1024]; static FILE *fp=NULL; char *ptr; debug=1; if(rbuff==NULL) return -1; *rbuff='\0'; if(fp==NULL){ fp=fopen("testdata.txt","r"); if(fp==NULL) return -1; } for(;fgets(buff,1000,fp);){ //猖乖コ〖ドを猴近 if(*buff=='*') break; for(ptr=buff;*ptr!='\0';ptr++){ if(*ptr=='\r'|| *ptr=='\n'){ *ptr='\0'; } } strcat(rbuff,buff); //インタ〖ネット猖乖コ〖ドを赁掐 strcat(rbuff,"\r\n"); } *rlen=strlen(rbuff); *caddr=htonl(10*256*256*256+168*256*256+1); *cport=SIP_PORT; *ret=0; if(*rlen ==0){ fclose(fp); fp=NULL; printf("NO Data to Recv\n"); }// dump_packet(rbuff,*rlen); return *rlen;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -