Andrei Pelinescu-Onciul 24 rokov pred
rodič
commit
4ac74c03d9
10 zmenil súbory, kde vykonal 214 pridanie a 50 odobranie
  1. 124 0
      action.c
  2. 19 0
      action.h
  3. 26 18
      forward.c
  4. 3 4
      forward.h
  5. 7 0
      msg_parser.h
  6. 13 12
      proxy.c
  7. 2 0
      proxy.h
  8. 17 13
      receive.c
  9. 2 2
      route.c
  10. 1 1
      route_struct.c

+ 124 - 0
action.c

@@ -0,0 +1,124 @@
+/*
+ * $Id$
+ */
+
+
+
+#include "action.h"
+#include "config.h"
+#include "error.h"
+#include "dprint.h"
+#include "proxy.h"
+
+#include <netdb.h>
+#include <stdlib.h>
+
+/* ret= 0 if action -> end of lis t(e.g DROP), >0
+   and >0 on error */
+int do_action(struct action* a, struct sip_msg* msg)
+{
+	int ret;
+	struct sockaddr_in* to;
+	struct proxy_l* p;
+
+	switch (a->type){
+		case DROP_T:
+				ret=0;
+			break;
+		case FORWARD_T:
+			if (a->p1_type!= PROXY_ST){
+				LOG(L_CRIT, "BUG: do_action: bad type %d\n", a->p1_type);
+				ret=E_BUG;
+				break;
+			}
+			ret=forward_request(msg, (struct proxy_l*)a->p1.data);
+			if (ret>=0) ret=1;
+			break;
+		case SEND_T:
+			to=(struct sockaddr_in*) malloc(sizeof(struct sockaddr));
+			if (to==0){
+				LOG(L_ERR, "ERROR: do_action: "
+							"memory allocation failure\n");
+				ret=E_OUT_OF_MEM;
+				break;
+			}
+			if (a->p1_type!= PROXY_ST){
+				LOG(L_CRIT, "BUG: do_action: bad type %d\n", a->p1_type);
+				ret=E_BUG;
+				break;
+			}
+			
+			p=(struct proxy_l*)a->p1.data;
+			
+			to->sin_family = AF_INET;
+			to->sin_port=(p->port)?htons(p->port):htons(SIP_PORT);
+			if (p->ok==0){
+				if (p->host.h_addr_list[p->addr_idx+1])
+					p->addr_idx++;
+				p->ok=1;
+			}
+			to->sin_addr.s_addr=*((long*)p->host.h_addr_list[p->addr_idx]);
+			p->tx++;
+			p->tx_bytes+=msg->len;
+			ret=udp_send(msg->orig, msg->len, to, sizeof(struct sockaddr));
+			free(to);
+			if (ret<0){
+				p->errors++;
+				p->ok=0;
+			}else ret=1;
+			
+			break;
+		case LOG_T:
+			LOG(a->p2.number, a->p1.string);
+			ret=1;
+			break;
+		case ERROR_T:
+			LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
+					"not implemented yet\n", a->p1.string, a->p2.string);
+			ret=1;
+			break;
+		case ROUTE_T:
+			LOG(L_NOTICE, "WARNING: do_action: route(%d) not implemented "
+							"yet\n", a->p1.number);
+			break;
+		case EXEC_T:
+			LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,",
+						" using dumb version...\n", a->p1.string);
+			ret=system(a->p1.string);
+			if (ret!=0){
+				LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
+			}
+			ret=1;
+			break;
+		default:
+			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
+	}
+	return ret;
+}
+
+
+
+/* returns: 0 on success, -1 on error */
+int run_actions(struct action* a, struct sip_msg* msg)
+{
+	struct action* t;
+	int ret;
+	
+	if (a==0){
+		LOG(L_ERR, "WARNING: run_actions: null action list\n");
+		ret=0;
+	}
+
+	for (t=a; t!=0; t=t->next){
+		ret=do_action(t, msg);
+		if(ret==0) break;
+		else if (ret<0){ ret=-1; goto error; }
+	}
+	ret=0;
+
+error:
+	return ret;
+}
+
+
+

+ 19 - 0
action.h

@@ -0,0 +1,19 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef action_h
+#define action_h
+
+#include "msg_parser.h"
+#include "route_struct.h"
+
+int do_action(struct action* a, struct sip_msg* msg);
+int run_actions(struct action* a, struct sip_msg* msg);
+
+
+
+
+
+#endif

+ 26 - 18
forward.c

@@ -58,19 +58,22 @@ int check_address(unsigned long ip, char *name, int resolver)
 
 
 
-int forward_request(char * orig, char* buf, 
-					 unsigned int len,
-					 struct sip_msg* msg,
-					 struct route_elem* re,
+int forward_request( struct sip_msg* msg,
+					 struct proxy_l * p,
 					 unsigned long source_ip)
 {
-	unsigned int new_len, via_len, received_len;
+	unsigned int len, new_len, via_len, received_len;
 	char line_buf[MAX_VIA_LINE_SIZE];
 	char received_buf[MAX_RECEIVED_SIZE];
 	char* new_buf;
+	char* orig;
+	char* buf;
 	int offset, s_offset, size;
 	struct sockaddr_in* to;
 
+	orig=msg->orig;
+	buf=msg->buf;
+	len=msg->len;
 	received_len=0;
 	new_buf=0;
 	to=0;
@@ -131,21 +134,21 @@ int forward_request(char * orig, char* buf,
 			len, new_len, via_len, received_len);
 
 	to->sin_family = AF_INET;
-	to->sin_port = (re->port)?htons(re->port):htons(SIP_PORT);
+	to->sin_port = (p->port)?htons(p->port):htons(SIP_PORT);
 	/* if error try next ip address if possible */
-	if (re->ok==0){
-		if (re->host.h_addr_list[re->current_addr_idx+1])
-			re->current_addr_idx++;
-		re->ok=1;
+	if (p->ok==0){
+		if (p->host.h_addr_list[p->addr_idx+1])
+			p->addr_idx++;
+		p->ok=1;
 	}
 	/* ? not 64bit clean?*/
-	to->sin_addr.s_addr=*((long*)re->host.h_addr_list[re->current_addr_idx]);
+	to->sin_addr.s_addr=*((long*)p->host.h_addr_list[p->addr_idx]);
 
-	re->tx++;
-	re->tx_bytes+=new_len;
+	p->tx++;
+	p->tx_bytes+=new_len;
 	if (udp_send(new_buf, new_len, to, sizeof(struct sockaddr))==-1){
-			re->errors++;
-			re->ok=0;
+			p->errors++;
+			p->ok=0;
 			goto error;
 	}
 
@@ -162,9 +165,7 @@ error:
 
 
 /* removes first via & sends msg to the second */
-int forward_reply(char * orig, char* buf, 
-					 unsigned int len,
-					 struct sip_msg* msg)
+int forward_reply(struct sip_msg* msg)
 {
 
 
@@ -173,7 +174,14 @@ int forward_reply(char * orig, char* buf,
 	int offset, s_offset, size;
 	struct hostent* he;
 	struct sockaddr_in* to;
+	char* orig;
+	char* buf;
+	unsigned int len;
+	
 
+	orig=msg->orig;
+	buf=msg->buf;
+	len=msg->len;
 	new_buf=0;
 	to=0;
 	to=(struct sockaddr_in*)malloc(sizeof(struct sockaddr));

+ 3 - 4
forward.h

@@ -8,15 +8,14 @@
 
 #include "msg_parser.h"
 #include "route.h"
+#include "proxy.h"
 
 
 int check_address(unsigned long ip, char *name, int resolver);
 
-int forward_request(char * orig, char* buf, unsigned int len,
-					 struct sip_msg* msg,  struct route_elem* re,
+int forward_request( struct sip_msg* msg,  struct proxy_l* p,
 					 unsigned long source_ip);
 
-int forward_reply(char * orig, char* buf, unsigned int len, 
-					struct sip_msg* msg);
+int forward_reply( struct sip_msg* msg);
 
 #endif

+ 7 - 0
msg_parser.h

@@ -64,8 +64,15 @@ struct sip_msg{
 	struct msg_start first_line;
 	struct via_body via1;
 	struct via_body via2;
+
 	unsigned int src_ip;
 	unsigned int dst_ip;
+	char* orig; /* original message copy */
+	char* buf;  /* scratch pad, holds a modfied message,
+				   via, etc. point into it */
+				   
+	unsigned int len; /* message len (orig) */
+	
 };
 
 

+ 13 - 12
proxy.c

@@ -8,6 +8,7 @@
 
 #include "proxy.h"
 #include "error.h"
+#include "dprint.h"
 
 #include <string.h>
 
@@ -30,9 +31,9 @@ struct proxy_l* find_proxy(char *name, unsigned short port)
 
 
 /* copies a hostent structure*, returns 0 on success, <0 on error*/
-int hostent_cpy(struct hostent *dst, struct hosten* src)
+int hostent_cpy(struct hostent *dst, struct hostent* src)
 {
-	int len, r;
+	int len, r,ret,i,len2;
 
 	/* start copying the host entry.. */
 	/* copy h_name */
@@ -55,7 +56,7 @@ int hostent_cpy(struct hostent *dst, struct hosten* src)
 	memset((void*)dst->h_aliases, 0, sizeof(char*) * (len+1) );
 	for (i=0;i<len;i++){
 		len2=strlen(src->h_aliases[i])+1;
-		dst->.h_aliases[i]=(char*)malloc(sizeof(char)*len2);
+		dst->h_aliases[i]=(char*)malloc(sizeof(char)*len2);
 		if (dst->h_aliases==0){
 			ret=E_OUT_OF_MEM;
 			free(dst->h_name);
@@ -71,19 +72,19 @@ int hostent_cpy(struct hostent *dst, struct hosten* src)
 	if (dst->h_addr_list==0){
 		ret=E_OUT_OF_MEM;
 		free(dst->h_name);
-		for(r=0; h_aliases[r]; r++)	free(dst->h_aliases[r]);
-		free h_aliases[r];
+		for(r=0; dst->h_aliases[r]; r++)	free(dst->h_aliases[r]);
+		free(dst->h_aliases[r]);
 		free(dst->h_aliases);
 		goto error;
 	}
-	memset((void*)dst->.h_addr_list, 0, sizeof(char*) * (len+1) );
+	memset((void*)dst->h_addr_list, 0, sizeof(char*) * (len+1) );
 	for (i=0;i<len;i++){
 		dst->h_addr_list[i]=(char*)malloc(sizeof(char)*src->h_length);
 		if (dst->h_addr_list[i]==0){
 			ret=E_OUT_OF_MEM;
 			free(dst->h_name);
-			for(r=0; h_aliases[r]; r++)	free(dst->h_aliases[r]);
-			free h_aliases[r];
+			for(r=0; dst->h_aliases[r]; r++)	free(dst->h_aliases[r]);
+			free(dst->h_aliases[r]);
 			free(dst->h_aliases);
 			for (r=0; r<i;r++) free(dst->h_addr_list[r]);
 			free(dst->h_addr_list);
@@ -94,7 +95,7 @@ int hostent_cpy(struct hostent *dst, struct hosten* src)
 
 	/* copy h_addr_type & length */
 	dst->h_addrtype=src->h_addrtype;
-	dst->host.h_length=src->h_length;
+	dst->h_length=src->h_length;
 	/*finished hostent copy */
 	
 	return 0;
@@ -108,8 +109,8 @@ error:
 
 struct proxy_l* add_proxy(char* name, unsigned short port)
 {
-	proxy_l* p;
-	struct hostent he;
+	struct proxy_l* p;
+	struct hostent* he;
 	
 	if ((p=find_proxy(name, port))!=0) return p;
 	p=(struct proxy_l*) malloc(sizeof(struct proxy_l));
@@ -117,7 +118,7 @@ struct proxy_l* add_proxy(char* name, unsigned short port)
 		LOG(L_CRIT, "ERROR: add_proxy: memory allocation failure\n");
 		goto error;
 	}
-	memset(p,0,sizeof(struct_proxy_l));
+	memset(p,0,sizeof(struct proxy_l));
 	p->name=name;
 	p->port=port;
 	he=gethostbyname(name);

+ 2 - 0
proxy.h

@@ -27,6 +27,8 @@ struct proxy_l{
 
 extern struct proxy_l* proxies;
 
+struct proxy_l* add_proxy(char* name, unsigned short port);
+
 
 #endif
 

+ 17 - 13
receive.c

@@ -15,15 +15,18 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
 {
 	struct sip_msg msg;
 	struct route_elem *re;
-	char * orig;
 
+	/* fill in msg */
+	msg.buf=buf;
+	msg.len=len;
+	msg.src_ip=src_ip;
 	/* make a copy of the message */
-	orig=(char*) malloc(len);
-	if (orig==0){
+	msg.orig=(char*) malloc(len);
+	if (msg.orig==0){
 		LOG(L_ERR, "ERROR:receive_msg: memory allocation failure\n");
 		goto error1;
 	}
-	memcpy(orig, buf, len);
+	memcpy(msg.orig, buf, len);
 	
 	if (parse_msg(buf,len, &msg)!=0){
 		goto error;
@@ -38,10 +41,7 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
 		/* check if neccesarry to add receive? */
 		
 		/* find route */
-		re=route_match(  msg.first_line.u.request.method,
-						 msg.first_line.u.request.uri,
-						 &rlist
-					  );
+		re=route_match( &msg, &rlist[0]);
 		if (re==0){
 			/* no route found, send back error msg? */
 			LOG(L_WARN, "WARNING: receive_msg: no route found!\n");
@@ -49,8 +49,12 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
 		}
 		re->tx++;
 		/* send msg */
-		DBG(" found route to: %s\n", re->host.h_name);
-		forward_request(orig, buf, len, &msg, re, src_ip);
+		DBG(" found route \n");
+		if (run_actions(re->actions)<0){
+			LOG(L_WARN, "WARNING: receive_msg: "
+					"error while trying actions\n");
+			goto error;
+		}
 	}else if (msg.first_line.type==SIP_REPLY){
 		/* sanity checks */
 		if (msg.via1.error!=VIA_PARSE_OK){
@@ -64,17 +68,17 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
 		/* check if via1 == us */
 		
 		/* send the msg */
-		if (forward_reply(orig, buf, len, &msg)==0){
+		if (forward_reply(&msg)==0){
 			DBG(" reply forwarded to %s:%d\n", 
 						msg.via2.host,
 						(unsigned short) msg.via2.port);
 		}
 	}
 skip:
-	free(orig);
+	free(msg.orig);
 	return 0;
 error:
-	free(orig);
+	free(msg.orig);
 error1:
 	return -1;
 }

+ 2 - 2
route.c

@@ -15,8 +15,8 @@
 #include <netdb.h>
 
 #include "route.h"
-#include "cfg_parser.h"
 #include "dprint.h"
+#include "proxy.h"
 
 /* main routing list */
 struct route_elem* rlist[RT_NO];
@@ -150,7 +150,7 @@ int fix_expr(struct expr* exp)
 int fix_actions(struct action* a)
 {
 	struct action *t;
-	struct proxy* p;
+	struct proxy_l* p;
 	char *tmp;
 	
 	for(t=a; t!=0; t=t->next){

+ 1 - 1
route_struct.c

@@ -234,7 +234,7 @@ void print_action(struct action* a)
 					printf("%d",t->p1.number);
 					break;
 			case IP_ST:
-					print_ip(t->p1.data);
+					print_ip(t->p1.number);
 					break;
 			default:
 					printf("type<%d>", t->p1_type);