Browse code

First working release

Andrei Pelinescu-Onciul authored on 04/09/2001 20:55:41
Showing 13 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,48 @@
1
+# $Id$
2
+#
3
+# sip_router makefile
4
+#
5
+
6
+sources= $(wildcard *.c)
7
+objs= $((sources:.c=.o)
8
+depends= $(sources:.c=.d)
9
+
10
+NAME=sip_router
11
+
12
+CC=gcc
13
+COPTS=-O2
14
+ALLDEP=Makefile
15
+
16
+MKDEP=gcc -M
17
+
18
+
19
+#implicit rules
20
+
21
+%.o:%.c $(ALLDEP)
22
+	$(CC) $(COPTS) -c $< -o $@
23
+
24
+%.d: %.c
25
+	$(MKDEP) $< >$@
26
+
27
+$(NAME): $(objs)
28
+	$(CC) $(COPTS) $(objs) -o $(NAME)
29
+
30
+.PHONY: all
31
+all: $(NAME)
32
+
33
+.PHONY: dep
34
+dep: $(depends)
35
+
36
+.PHONY: clean
37
+clean:
38
+	-rm $(objs) $(NAME)
39
+
40
+.PHONY: proper
41
+proper: clean
42
+	-rm $(depends)
43
+
44
+include $(depends)
45
+
46
+
47
+
48
+
... ...
@@ -7,6 +7,7 @@
7 7
 #include <stdio.h>
8 8
 
9 9
 #include "cfg_parser.h"
10
+#include "msg_parser.h" /* parse_hostport */
10 11
 #include "dprint.h"
11 12
 #include "parser_f.h"
12 13
 #include "route.h"
... ...
@@ -40,28 +41,23 @@ int cfg_parse_line(char* line, struct cfg_line* cl)
40 41
 	cl->method=tmp;
41 42
 	tmp=eat_token(cl->method,end-cl->method);
42 43
 	if (tmp==end) goto error;
43
-	printf("%d\n", tmp-line);
44 44
 	*tmp=0;
45 45
 	tmp++;
46 46
 	cl->uri=eat_space(tmp,end-tmp);
47 47
 	if (tmp==end) goto error;
48 48
 	tmp=eat_token(cl->uri,end-cl->uri);
49 49
 	if (tmp==end) goto error;
50
-	printf("%d\n", tmp-line);
51 50
 	*tmp=0;
52 51
 	tmp++;
53 52
 	cl->address=eat_space(tmp,end-tmp);
54 53
 	if (tmp==end) goto error;
55 54
 	tmp=eat_token(cl->address, end-cl->address);
56
-	printf("%d(%02x)\n", tmp-line, *tmp);
57 55
 	if (tmp<end) {
58 56
 		*tmp=0;
59 57
 		if (tmp+1<end){
60 58
 			if (!is_empty(tmp+1,end-tmp-1)){
61
-				printf("%d(%02x) e: %d\n", tmp-line, *tmp, end-line);
62 59
 				/* check if comment */
63 60
 				tmp=eat_space(tmp+1, end-tmp-1);
64
-				printf("%d(%02x) e: %d\n", tmp-line, *tmp, end-line);
65 61
 				if (*tmp!='#'){
66 62
 					/* extra chars at the end of line */
67 63
 					goto error;
... ...
@@ -69,7 +65,11 @@ int cfg_parse_line(char* line, struct cfg_line* cl)
69 65
 			}
70 66
 		}
71 67
 	}
72
-		
68
+	/* find port */
69
+	if (parse_hostport(cl->address, &tmp, &cl->port)==0){
70
+			goto error;
71
+	}
72
+	
73 73
 	cl->type=CFG_RULE;
74 74
 skip:
75 75
 	return 0;
... ...
@@ -20,6 +20,7 @@ struct cfg_line{
20 20
 	char* method;
21 21
 	char* uri;
22 22
 	char* address;
23
+	short int port;
23 24
 };
24 25
 
25 26
 
26 27
new file mode 100644
... ...
@@ -0,0 +1,18 @@
1
+/*
2
+ *  $Id
3
+ */
4
+
5
+
6
+
7
+#ifndef config_h
8
+#define config_h
9
+
10
+/* default sip port if none specified */
11
+#define SIP_PORT 5060
12
+
13
+#define CFG_FILE "./sip_router.cfg"
14
+
15
+/* receive buffer size */
16
+#define BUF_SIZE 65507
17
+
18
+#endif
... ...
@@ -4,17 +4,19 @@
4 4
 
5 5
 
6 6
 #include <string.h>
7
+#include <netdb.h>
8
+#include <netinet/in.h>
7 9
 
8 10
 #include "forward.h"
11
+#include "config.h"
9 12
 #include "msg_parser.h"
10 13
 #include "route.h"
11 14
 #include "dprint.h"
15
+#include "udp_server.h"
12 16
 
13 17
 #define MAX_VIA_LINE_SIZE      240
14 18
 #define MAX_RECEIVED_SIZE  57
15 19
 
16
-#define our_address "dorian.fokus.gmd.de"
17
-#define our_port 1234
18 20
 
19 21
 
20 22
 int forward_request(char * orig, char* buf, 
... ...
@@ -27,12 +29,12 @@ int forward_request(char * orig, char* buf,
27 29
 	char received_buf[MAX_RECEIVED_SIZE];
28 30
 	char* new_buf;
29 31
 	int offset, s_offset, size;
32
+	struct sockaddr_in to;
30 33
 
31 34
 	received_len=0;
32
-	printf("0\n");
33 35
 
34 36
 	via_len=snprintf(line_buf, MAX_VIA_LINE_SIZE, "Via: SIP/2.0/UDP %s:%d\r\n",
35
-						our_address, our_port);
37
+						our_name, our_port);
36 38
 	/* check if received needs to be added */
37 39
 	/* if check_address(source_ip, msg->via1.host) */
38 40
 	received_len=snprintf(received_buf, MAX_RECEIVED_SIZE, ";received=%s",
... ...
@@ -42,49 +44,67 @@ int forward_request(char * orig, char* buf,
42 44
 	new_buf=(char*)malloc(new_len+1);
43 45
 	if (new_buf==0){
44 46
 		DPrint("ERROR: forward_request: out of memory\n");
45
-		goto error;
47
+		goto error1;
46 48
 	}
47
-	printf("1\n");
48
- /* copy msg till first via */
49
- 	offset=s_offset=0;
50
- 	size=msg->via1.hdr-buf;
51
- 	memcpy(new_buf, orig, size);
49
+/* copy msg till first via */
50
+	offset=s_offset=0;
51
+	size=msg->via1.hdr-buf;
52
+	memcpy(new_buf, orig, size);
52 53
 	offset+=size;
53 54
 	s_offset+=size;
54
-	printf("2\n");
55 55
  /* add our via */
56
- 	memcpy(new_buf+offset, line_buf, via_len);
56
+	memcpy(new_buf+offset, line_buf, via_len);
57 57
 	offset+=via_len;
58
-	printf("3\n");
59 58
  /* modify original via if neccesarry (received=...)*/
60
- 	if (received_len){
59
+	if (received_len){
61 60
 		if (msg->via1.params){
62 61
 				size= msg->via1.params-msg->via1.hdr-1; /*compensate for ';' */
63 62
 		}else{
64 63
 				size= msg->via1.host-msg->via1.hdr+strlen(msg->via1.host);
65 64
 				if (msg->via1.port!=0){
66
-					size+=strlen(msg->via1.hdr+size+1);
65
+					size+=strlen(msg->via1.hdr+size+1)+1; /* +1 for ':'*/
67 66
 				}
68 67
 		}
69 68
 		memcpy(new_buf+offset, orig+s_offset, 
70 69
 								size);
71 70
 		offset+=size;
72 71
 		s_offset+=size;
73
-		printf("4\n");
74 72
 		memcpy(new_buf+offset, received_buf, received_len);
75
-		printf("5\n");
76 73
 		offset+=received_len;
77 74
 	}
78 75
  	/* copy the rest of the msg */
79 76
  	memcpy(new_buf+offset, orig+s_offset, len-s_offset);
80
-	printf("6\n");
81 77
 	new_buf[new_len]=0;
82 78
 
83 79
 	 /* send it! */
84
-	 printf("Sending:\n%s.\n", new_buf);
85
-	 
80
+	printf("Sending:\n%s.\n", new_buf);
81
+	printf("orig. len=%d, new_len=%d, via_len=%d, received_len=%d\n",
82
+			len, new_len, via_len, received_len);
83
+
84
+	to.sin_family = AF_INET;
85
+	to.sin_port = (re->port)?htons(re->port):htons(SIP_PORT);
86
+	/* if error try next ip address if possible */
87
+	if (re->ok==0){
88
+		if (re->host.h_addr_list[re->current_addr_idx+1])
89
+			re->current_addr_idx++;
90
+		re->ok=1;
91
+	}
92
+	/* ? not 64bit clean?*/
93
+	to.sin_addr.s_addr=*((long*)re->host.h_addr_list[re->current_addr_idx]);
94
+
95
+	re->tx++;
96
+	re->tx_bytes+=new_len;
97
+	if (udp_send(new_buf, new_len, &to, sizeof(to))==-1){
98
+			re->errors++;
99
+			re->ok=0;
100
+			goto error;
101
+	}
102
+
103
+	free(new_buf);
86 104
 	return 0;
87 105
 error:
106
+	free(new_buf);
107
+error1:
88 108
 	return -1;
89 109
 
90 110
 }
... ...
@@ -101,37 +121,51 @@ int forward_reply(char * orig, char* buf,
101 121
 	unsigned int new_len, via_len;
102 122
 	char* new_buf;
103 123
 	int offset, s_offset, size;
124
+	struct hostent* he;
125
+	struct sockaddr_in to;
104 126
 
105 127
 
106
-	/* we must remove first via */
128
+	/* we must remove the first via */
107 129
 	via_len=msg->via1.size;
108 130
 	size=msg->via1.hdr-buf;
109 131
 	if (msg->via1.next){
110
-		via_len-=strlen(msg->via1.hdr)+1; /* +1 from ':' */
132
+		/* keep hdr =substract hdr size +1 (hdr':') and add
133
+		 */
134
+		via_len-=strlen(msg->via1.hdr)+1;
111 135
 		size+=strlen(msg->via1.hdr)+1;
112 136
 	}
113 137
 	new_len=len-size;
114
-	printf("r1\n");
115 138
 	new_buf=(char*)malloc(new_len);
116 139
 	if (new_buf==0){
117 140
 		DPrint("ERROR: forward_reply: out of memory\n");
118 141
 		goto error;
119 142
 	}
120
-	printf("r2\n");
121 143
 	memcpy(new_buf, orig, size);
122 144
 	offset=size;
123 145
 	s_offset=size+via_len;
124
-	printf("r3\n");
125 146
 	memcpy(new_buf+offset,orig+s_offset, len-s_offset);
126
-	printf("r4\n");
127 147
 	 /* send it! */
128 148
 	printf("Sending: to %s:%d, \n%s.\n",
129 149
 			msg->via2.host, 
130 150
 			(unsigned short)msg->via2.port,
131 151
 			new_buf);
152
+	/* fork? gethostbyname will probably block... */
153
+	he=gethostbyname(msg->via2.host);
154
+	if (he==0){
155
+		DPrint("ERROR:forward_reply:gethostbyname failure\n");
156
+		goto error;
157
+	}
158
+	to.sin_family = AF_INET;
159
+	to.sin_port = (msg->via2.port)?htons(msg->via2.port):htons(SIP_PORT);
160
+	to.sin_addr.s_addr=*((long*)he->h_addr_list[0]);
161
+	
162
+	if (udp_send(new_buf,new_len, &to, sizeof(to))==-1)
163
+		goto error;
132 164
 	
165
+	free(new_buf);
133 166
 	return 0;
134 167
 
135 168
 error:
169
+	if (new_buf) free(new_buf);
136 170
 	return -1;
137 171
 }
... ...
@@ -5,15 +5,17 @@
5 5
 #include <stdio.h>
6 6
 #include <errno.h>
7 7
 #include <string.h>
8
+#include <netdb.h>
8 9
 
10
+#include "config.h"
9 11
 #include "dprint.h"
10 12
 #include "route.h"
13
+#include "udp_server.h"
11 14
 
12
-#define CFG_FILE "./sip_router.cfg"
13 15
 
14 16
 
15 17
 /* debuging function */
16
-
18
+/*
17 19
 void receive_stdin_loop()
18 20
 {
19 21
 	#define BSIZE 1024
... ...
@@ -27,7 +29,9 @@ void receive_stdin_loop()
27 29
 		printf("-------------------------\n");
28 30
 	}
29 31
 }
32
+*/
30 33
 
34
+#define NAME "dorian.fokus.gmd.de"
31 35
 
32 36
 
33 37
 int main(int argc, char** argv)
... ...
@@ -35,12 +39,29 @@ int main(int argc, char** argv)
35 39
 
36 40
 	char * cfg_file;
37 41
 	FILE* cfg_stream;
42
+	struct hostent* he;
38 43
 
39 44
 	cfg_file=CFG_FILE;
40 45
 	
41 46
 	/* process command line (get port no, cfg. file path etc) */
42 47
 	/* ...*/
43 48
 
49
+	our_port=SIP_PORT;
50
+	our_name=NAME;
51
+	/* get ip */
52
+	he=gethostbyname(our_name);
53
+	if (he==0){
54
+		DPrint("ERROR: could not resolve %s\n", our_name);
55
+		goto error;
56
+	}
57
+	our_address=*((long*)he->h_addr_list[0]);
58
+	printf("Listening on %s[%x]:%d\n",our_name,
59
+				(unsigned long)our_address,
60
+				(unsigned short)our_port);
61
+		
62
+	
63
+	
64
+
44 65
 	/* load config file or die */
45 66
 	cfg_stream=fopen (cfg_file, "r");
46 67
 	if (cfg_stream==0){
... ...
@@ -57,12 +78,12 @@ int main(int argc, char** argv)
57 78
 	print_rl();
58 79
 
59 80
 
60
-
81
+	/* init_daemon? */
82
+	if (udp_init(our_address,our_port)==-1) goto error;
61 83
 	/* start/init other processes/threads ? */
62 84
 
63 85
 	/* receive loop */
64
-
65
-	receive_stdin_loop();
86
+	udp_rcv_loop();
66 87
 
67 88
 
68 89
 error:
... ...
@@ -390,13 +390,18 @@ int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
390 390
 							DPrint("ERROR: parsing via body: %s\n", first_via);
391 391
 							goto error;
392 392
 						}
393
-						vb1.size=bar-first_via+first_via-vb1.hdr;
393
+						
394
+						vb1.size=bar-first_via+first_via-vb1.hdr; 
394 395
 						
395 396
 						/* compact via */
396 397
 						if (vb1.next) {
397 398
 							second_via=vb1.next;
398 399
 							/* not interested in the rest of the header */
399 400
 							goto skip;
401
+						}else{
402
+						/*  add 1 (we don't see the trailing lf which
403
+						 *  was zeroed by get_hfr_field */
404
+							vb1.size+=1;
400 405
 						}
401 406
 				}else if (second_via==0){
402 407
 							second_via=hf.body;
... ...
@@ -423,7 +428,8 @@ skip:
423 428
 			DPrint("ERROR: parsing via body: %s\n", second_via);
424 429
 			goto error;
425 430
 		}
426
-		vb2.size=tmp-second_via;
431
+		vb2.size=tmp-second_via; 
432
+		if (vb2.next==0) vb2.size+=1; /* +1 from trailing lf */
427 433
 		if (vb2.hdr) vb2.size+=second_via-vb2.hdr;
428 434
 	}
429 435
 	
... ...
@@ -162,7 +162,7 @@ int add_rule(struct cfg_line* cl, struct route_elem** head)
162 162
 	/*finished hostent copy */
163 163
 
164 164
 	
165
-	
165
+	re->port=cl->port;
166 166
 	re->current_addr_idx=0;
167 167
 	re->ok=1;
168 168
 
... ...
@@ -205,7 +205,7 @@ void print_rl()
205 205
 	int i,j;
206 206
 
207 207
 	if (rlist==0){
208
-		DPrint("the routing table is emty\n");
208
+		DPrint("the routing table is empty\n");
209 209
 		return;
210 210
 	}
211 211
 	
... ...
@@ -221,7 +221,8 @@ void print_rl()
221 221
 				(unsigned char) t->host.h_addr_list[j][3]
222 222
 				  );
223 223
 				
224
-		DPrint("\n   Statistics: tx=%d, errors=%d, tx_bytes=%d, idx=%d\n",
224
+		DPrint("\n   port:%d\n", (unsigned short)t->port);
225
+		DPrint("   Statistics: tx=%d, errors=%d, tx_bytes=%d, idx=%d\n",
225 226
 				t->tx, t->errors, t->tx_bytes, t->current_addr_idx);
226 227
 	}
227 228
 
... ...
@@ -21,6 +21,8 @@ struct route_elem{
21 21
 	regex_t uri;
22 22
 	struct hostent host;
23 23
 	int current_addr_idx;
24
+	short int port;
25
+	short int reserved; /* pad */
24 26
 	int ok; /* set to 0 if an error was found sendig a pkt*/
25 27
 	/*counters*/
26 28
 	int errors;
... ...
@@ -5,7 +5,7 @@
5 5
 # (warning: re cannot contain space)
6 6
 
7 7
 ^R.*        ^sip:.*@dorian.*   ekina.fokus.gmd.de        
8
-^INVITE     .*                 ape             # my laptop
8
+^INVITE     .*                 ape:5061             # my laptop
9 9
 .           .                  192.168.46.55
10 10
 .*			.*andrei		   helios.fokus.gmd.de
11 11
 
12 12
similarity index 100%
13 13
rename from test.c
14 14
rename to test.c.bak
15 15
new file mode 100644
... ...
@@ -0,0 +1,103 @@
1
+/*
2
+ * $Id$
3
+ */
4
+
5
+#include <sys/types.h>
6
+#include <sys/socket.h>
7
+#include <netinet/in.h>
8
+#include <errno.h>
9
+
10
+
11
+#include "udp_server.h"
12
+#include "config.h"
13
+#include "dprint.h"
14
+
15
+
16
+int udp_sock;
17
+
18
+char* our_name;
19
+unsigned long our_address;
20
+unsigned short our_port;
21
+
22
+
23
+
24
+int udp_init(unsigned long ip, unsigned short port)
25
+{
26
+	struct sockaddr_in addr;
27
+
28
+	addr.sin_family=AF_INET;
29
+	addr.sin_port=htons(port);
30
+	addr.sin_addr.s_addr=ip;
31
+
32
+	udp_sock = socket(PF_INET, SOCK_DGRAM, 0);
33
+	if (udp_sock==-1){
34
+		DPrint("ERROR: udp_init: socket: %s\n", strerror());
35
+		goto error;
36
+	}
37
+
38
+	if (bind(udp_sock, (struct sockaddr*) &addr, sizeof(addr))==-1){
39
+		DPrint("ERROR: udp_init: socket: %s\n", strerror());
40
+		goto error;
41
+	}
42
+
43
+	/* set sock opts? */
44
+
45
+	return 0;
46
+
47
+error:
48
+	return -1;
49
+}
50
+
51
+
52
+
53
+int udp_rcv_loop()
54
+{
55
+	int len;
56
+	char buf[BUF_SIZE+1];
57
+	struct sockaddr* from;
58
+	int fromlen;
59
+
60
+	from=(struct sockaddr*) malloc(sizeof(struct sockaddr));
61
+	if (from==0){
62
+		DPrint("ERROR: udp_rcv_loop: out of memory\n");
63
+		goto error;
64
+	}
65
+
66
+	for(;;){
67
+		fromlen=sizeof(*from);
68
+		len=recvfrom(udp_sock, buf, BUF_SIZE, 0, from, &fromlen);
69
+		if (len==-1){
70
+			DPrint("ERROR: udp_rcv_loop:recvfrom: %s\n", strerror());
71
+			if (errno==EINTR)	goto skip;
72
+			else goto error;
73
+		}
74
+		/*debugging, make print* msg work */
75
+		buf[len+1]=0;
76
+
77
+		receive_msg(buf, len, from, fromlen);
78
+
79
+	skip: /* do other stuff */
80
+		
81
+	}
82
+
83
+	return 0;
84
+	
85
+error:
86
+	return -1;
87
+}
88
+
89
+
90
+
91
+/* which socket to use? main socket or new one? */
92
+int udp_send(char *buf, int len, struct sockaddr*  to, int tolen)
93
+{
94
+
95
+	int n;
96
+again:
97
+	n=sendto(udp_sock, buf, len, 0, to, tolen);
98
+	if (n==-1){
99
+		DPrint("ERROR: udp_send: sendto: %s\n", strerror());
100
+		if (errno==EINTR) goto again;
101
+	}
102
+	return n;
103
+}
0 104
new file mode 100644
... ...
@@ -0,0 +1,20 @@
1
+/*
2
+ * $Id$
3
+ */
4
+
5
+#ifndef udp_server_h
6
+#define udp_server_h
7
+
8
+
9
+
10
+extern int udp_sock;
11
+
12
+extern char* our_name;
13
+extern unsigned long  our_address;
14
+extern unsigned short our_port;
15
+
16
+int udp_init(unsigned long ip, unsigned short port);
17
+int udp_rcv_loop();
18
+
19
+
20
+#endif