Browse Source

- improved forward_request
- wrote fast inet_ntoa replacement
(no str in this version)

Andrei Pelinescu-Onciul 24 years ago
parent
commit
b2e71d5bd6
5 changed files with 134 additions and 9 deletions
  1. 12 0
      config.h
  2. 96 2
      forward.c
  3. 3 0
      globals.h
  4. 21 1
      main.c
  5. 2 6
      test/test-throughput.cfg

+ 12 - 0
config.h

@@ -30,4 +30,16 @@
 
 #define MAX_URI_SIZE 1024	/* used when rewriting URIs */
 
+#define MY_VIA "Via: SIP/2.0/UDP "
+#define MY_VIA_LEN 17
+
+
+#define MAX_PORT_LEN 7 /* ':' + max 5 letters + \0 */
+#define CRLF "\r\n"
+#define CRLF_LEN 2
+
+#define RECEIVED ";received="
+#define RECEIVED_LEN 10
+
+
 #endif

+ 96 - 2
forward.c

@@ -32,6 +32,67 @@
 #include "stats.h"
 #endif
 
+
+static char q_inet_itoa_buf[16]; /* 123.567.901.345\0 */
+/* faster than inet_ntoa */
+__inline char* q_inet_itoa(unsigned long ip)
+{
+	unsigned char* p;
+	unsigned char a,b,c;  /* abc.def.ghi.jkl */
+	int offset;
+	int r;
+	p=(unsigned char*)&ip;
+
+	offset=0;
+	/* unrolled loops (faster)*/
+	for(r=0;r<3;r++){
+		a=p[r]/100;
+		c=p[r]%10;
+		b=p[r]%100/10;
+		if (a){
+			q_inet_itoa_buf[offset]=a+'0';
+			q_inet_itoa_buf[offset+1]=b+'0';
+			q_inet_itoa_buf[offset+2]=c+'0';
+			q_inet_itoa_buf[offset+3]='.';
+			offset+=4;
+		}else if (b){
+			q_inet_itoa_buf[offset]=b+'0';
+			q_inet_itoa_buf[offset+1]=c+'0';
+			q_inet_itoa_buf[offset+2]='.';
+			offset+=3;
+		}else{
+			q_inet_itoa_buf[offset]=c+'0';
+			q_inet_itoa_buf[offset+1]='.';
+			offset+=2;
+		}
+	}
+	/* last number */
+	a=p[r]/100;
+	c=p[r]%10;
+	b=p[r]%100/10;
+	if (a){
+		q_inet_itoa_buf[offset]=a+'0';
+		q_inet_itoa_buf[offset+1]=b+'0';
+		q_inet_itoa_buf[offset+2]=c+'0';
+		q_inet_itoa_buf[offset+3]=0;
+	}else if (b){
+		q_inet_itoa_buf[offset]=b+'0';
+		q_inet_itoa_buf[offset+1]=c+'0';
+		q_inet_itoa_buf[offset+2]=0;
+	}else{
+		q_inet_itoa_buf[offset]=c+'0';
+		q_inet_itoa_buf[offset+1]=0;
+	}
+	
+	return q_inet_itoa_buf;
+}
+		
+		
+
+		
+		
+	
+
 /* checks if ip is in host(name) and ?host(ip)=name? 
  * ip must be in network byte order!
  *  resolver = DO_DNS | DO_REV_DNS; if 0 no dns check is made
@@ -42,9 +103,10 @@ int check_address(unsigned long ip, char *name, int resolver)
 	int i;
 	
 	/* maybe we are lucky and name it's an ip */
-	if (strcmp(name, inet_ntoa( *(struct in_addr *)&ip ))==0)
+	if (strcmp(name, q_inet_itoa( /* *(struct in_addr *)&*/ip ))==0)
 		return 0;
 	if (resolver&DO_DNS){ 
+		DBG("check_address: doing dns lookup\n");
 		/* try all names ips */
 		he=gethostbyname(name);
 		for(i=0;he && he->h_addr_list[i];i++){
@@ -53,7 +115,8 @@ int check_address(unsigned long ip, char *name, int resolver)
 		}
 	}
 	if (resolver&DO_REV_DNS){
-	print_ip(ip);
+		DBG("check_address: doing rev. dns lookup\n");
+		print_ip(ip);
 		/* try reverse dns */
 		he=gethostbyaddr((char*)&ip, sizeof(ip), AF_INET);
 		if (he && (strcmp(he->h_name, name)==0))
@@ -73,6 +136,8 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
 	unsigned int len, new_len, via_len, received_len, uri_len;
 	char* line_buf;
 	char* received_buf;
+	char* tmp;
+	int tmp_len;
 	char* new_buf;
 	char* orig;
 	char* buf;
@@ -102,8 +167,29 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
 		LOG(L_ERR, "ERROR: forward_request: out of memory\n");
 		goto error1;
 	}
+/*
 	via_len=snprintf(line_buf, MAX_VIA_LINE_SIZE, "Via: SIP/2.0/UDP %s:%d\r\n",
 						names[0], port_no);
+*/
+	via_len=MY_VIA_LEN+names_len[0]; /* space included in MY_VIA*/
+	if ((via_len+port_no_str_len+CRLF_LEN)<MAX_VIA_LINE_SIZE){
+		memcpy(line_buf, MY_VIA, MY_VIA_LEN);
+		memcpy(line_buf+MY_VIA_LEN, names[0], names_len[0]);
+		if (port_no!=SIP_PORT){
+			memcpy(line_buf+via_len, port_no_str, port_no_str_len);
+			via_len+=port_no_str_len;
+		}
+		memcpy(line_buf+via_len, CRLF, CRLF_LEN);
+		via_len+=CRLF_LEN;
+		line_buf[via_len]=0; /* null terminate the string*/
+	}else{
+		LOG(L_ERR, "forward_request: ERROR: via too long (%d)\n",
+				via_len);
+		goto error1;
+	}
+
+		
+	
 	/* check if received needs to be added */
 	if (check_address(source_ip, msg->via1.host, received_dns)!=0){
 		received_buf=malloc(sizeof(char)*MAX_RECEIVED_SIZE);
@@ -111,9 +197,17 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
 			LOG(L_ERR, "ERROR: forward_request: out of memory\n");
 			goto error1;
 		}
+		/*
 		received_len=snprintf(received_buf, MAX_RECEIVED_SIZE,
 								";received=%s", 
 								inet_ntoa(*(struct in_addr *)&source_ip));
+		*/
+		memcpy(received_buf, RECEIVED, RECEIVED_LEN);
+		tmp=q_inet_itoa( /* *(struct in_addr *)& */source_ip);
+		tmp_len=strlen(tmp);
+		received_len=RECEIVED_LEN+tmp_len;
+		memcpy(received_buf+RECEIVED_LEN, tmp, tmp_len);
+		received_buf[received_len]=0; /*null terminate it */
 	}
 	
 	/* add via header to the list */

+ 3 - 0
globals.h

@@ -16,8 +16,11 @@
 
 extern char * cfg_file;
 extern unsigned short port_no;
+extern char port_no_str[];
+extern int port_no_str_len;
 extern unsigned int maxbuffer;
 extern char * names[];
+extern int names_len[];
 extern unsigned long addresses[];
 extern int addresses_no;
 extern int children_no;

+ 21 - 1
main.c

@@ -34,7 +34,7 @@
 
 
 static char id[]="@(#) $Id$";
-static char version[]="ser 0.8.3.1";
+static char version[]="ser 0.8.3.2";
 static char flags[]="NOCR:"
 #ifdef NOCR
 "On"
@@ -98,6 +98,8 @@ void receive_stdin_loop()
 
 char* cfg_file = 0;
 unsigned short port_no = 0; /* port on which we listen */
+char port_no_str[MAX_PORT_LEN];
+int port_no_str_len=0;
 unsigned int maxbuffer = 128*1024; /* maximum buffer size we do not want to exceed
 				      durig the auto-probing procedure; may be
 				      re-configured */
@@ -110,6 +112,7 @@ int received_dns = 0;      /* use dns and/or rdns or to see if we need to
                               add a ;received=x.x.x.x to via: */
 
 char* names[MAX_LISTEN];               /* our names */
+int names_len[MAX_LISTEN];    /* lengths of the names*/
 unsigned long addresses[MAX_LISTEN];   /* our ips */
 int addresses_no=0;                    /* number of names/ips */
 
@@ -383,6 +386,18 @@ int main(int argc, char** argv)
 
 	/* fix parameters */
 	if (port_no<=0) port_no=SIP_PORT;
+	port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", 
+				(unsigned short) port_no);
+	if (port_no_str_len<0){
+		fprintf(stderr, "ERROR: bad port number: %d\n", port_no);
+		goto error;
+	}
+	/* on some system snprintf return really strange things if it does not have
+	 * enough space */
+	port_no_str_len=
+				(port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
+
+	
 	if (children_no<=0) children_no=CHILD_NO;
 	if (addresses_no==0) {
 		/* get our address, only the first one */
@@ -400,6 +415,11 @@ int main(int argc, char** argv)
 		addresses_no++;
 	}
 
+	/*get name lens*/
+	for(r=0; r<addresses_no; r++){
+		names_len[r]=strlen(names[r]);
+	}
+
 #ifdef STATS
 	/* jku: initialize statistic */
  	memset(&stats,0,sizeof(struct stats_s));

+ 2 - 6
test/test-throughput.cfg

@@ -1,4 +1,4 @@
-debug=9			# for speed
+debug=0			# for speed
 check_via=0
 dns=off
 rev_dns=off
@@ -8,10 +8,6 @@ children=8
 
 route{
 
-	if ( method=~'^INV' && uri=~'iptel\.org' ){
-		forward(127.0.0.1, 5060);
-		drop;
-	};
-	log("no rule for this packet => dropping\n");
+forward(127.0.0.1,5061);
 }