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 @@
0
+# $Id$
1
+#
2
+# sip_router makefile
3
+#
4
+
5
+sources= $(wildcard *.c)
6
+objs= $((sources:.c=.o)
7
+depends= $(sources:.c=.d)
8
+
9
+NAME=sip_router
10
+
11
+CC=gcc
12
+COPTS=-O2
13
+ALLDEP=Makefile
14
+
15
+MKDEP=gcc -M
16
+
17
+
18
+#implicit rules
19
+
20
+%.o:%.c $(ALLDEP)
21
+	$(CC) $(COPTS) -c $< -o $@
22
+
23
+%.d: %.c
24
+	$(MKDEP) $< >$@
25
+
26
+$(NAME): $(objs)
27
+	$(CC) $(COPTS) $(objs) -o $(NAME)
28
+
29
+.PHONY: all
30
+all: $(NAME)
31
+
32
+.PHONY: dep
33
+dep: $(depends)
34
+
35
+.PHONY: clean
36
+clean:
37
+	-rm $(objs) $(NAME)
38
+
39
+.PHONY: proper
40
+proper: clean
41
+	-rm $(depends)
42
+
43
+include $(depends)
44
+
45
+
46
+
47
+
... ...
@@ -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 40
 	cl->method=tmp;
41 41
 	tmp=eat_token(cl->method,end-cl->method);
42 42
 	if (tmp==end) goto error;
43
-	printf("%d\n", tmp-line);
44 43
 	*tmp=0;
45 44
 	tmp++;
46 45
 	cl->uri=eat_space(tmp,end-tmp);
47 46
 	if (tmp==end) goto error;
48 47
 	tmp=eat_token(cl->uri,end-cl->uri);
49 48
 	if (tmp==end) goto error;
50
-	printf("%d\n", tmp-line);
51 49
 	*tmp=0;
52 50
 	tmp++;
53 51
 	cl->address=eat_space(tmp,end-tmp);
54 52
 	if (tmp==end) goto error;
55 53
 	tmp=eat_token(cl->address, end-cl->address);
56
-	printf("%d(%02x)\n", tmp-line, *tmp);
57 54
 	if (tmp<end) {
58 55
 		*tmp=0;
59 56
 		if (tmp+1<end){
60 57
 			if (!is_empty(tmp+1,end-tmp-1)){
61
-				printf("%d(%02x) e: %d\n", tmp-line, *tmp, end-line);
62 58
 				/* check if comment */
63 59
 				tmp=eat_space(tmp+1, end-tmp-1);
64
-				printf("%d(%02x) e: %d\n", tmp-line, *tmp, end-line);
65 60
 				if (*tmp!='#'){
66 61
 					/* extra chars at the end of line */
67 62
 					goto error;
... ...
@@ -69,7 +65,11 @@ int cfg_parse_line(char* line, struct cfg_line* cl)
69 69
 			}
70 70
 		}
71 71
 	}
72
-		
72
+	/* find port */
73
+	if (parse_hostport(cl->address, &tmp, &cl->port)==0){
74
+			goto error;
75
+	}
76
+	
73 77
 	cl->type=CFG_RULE;
74 78
 skip:
75 79
 	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 @@
0
+/*
1
+ *  $Id
2
+ */
3
+
4
+
5
+
6
+#ifndef config_h
7
+#define config_h
8
+
9
+/* default sip port if none specified */
10
+#define SIP_PORT 5060
11
+
12
+#define CFG_FILE "./sip_router.cfg"
13
+
14
+/* receive buffer size */
15
+#define BUF_SIZE 65507
16
+
17
+#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 27
 	char received_buf[MAX_RECEIVED_SIZE];
28 28
 	char* new_buf;
29 29
 	int offset, s_offset, size;
30
+	struct sockaddr_in to;
30 31
 
31 32
 	received_len=0;
32
-	printf("0\n");
33 33
 
34 34
 	via_len=snprintf(line_buf, MAX_VIA_LINE_SIZE, "Via: SIP/2.0/UDP %s:%d\r\n",
35
-						our_address, our_port);
35
+						our_name, our_port);
36 36
 	/* check if received needs to be added */
37 37
 	/* if check_address(source_ip, msg->via1.host) */
38 38
 	received_len=snprintf(received_buf, MAX_RECEIVED_SIZE, ";received=%s",
... ...
@@ -42,49 +44,67 @@ int forward_request(char * orig, char* buf,
42 42
 	new_buf=(char*)malloc(new_len+1);
43 43
 	if (new_buf==0){
44 44
 		DPrint("ERROR: forward_request: out of memory\n");
45
-		goto error;
45
+		goto error1;
46 46
 	}
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);
47
+/* copy msg till first via */
48
+	offset=s_offset=0;
49
+	size=msg->via1.hdr-buf;
50
+	memcpy(new_buf, orig, size);
52 51
 	offset+=size;
53 52
 	s_offset+=size;
54
-	printf("2\n");
55 53
  /* add our via */
56
- 	memcpy(new_buf+offset, line_buf, via_len);
54
+	memcpy(new_buf+offset, line_buf, via_len);
57 55
 	offset+=via_len;
58
-	printf("3\n");
59 56
  /* modify original via if neccesarry (received=...)*/
60
- 	if (received_len){
57
+	if (received_len){
61 58
 		if (msg->via1.params){
62 59
 				size= msg->via1.params-msg->via1.hdr-1; /*compensate for ';' */
63 60
 		}else{
64 61
 				size= msg->via1.host-msg->via1.hdr+strlen(msg->via1.host);
65 62
 				if (msg->via1.port!=0){
66
-					size+=strlen(msg->via1.hdr+size+1);
63
+					size+=strlen(msg->via1.hdr+size+1)+1; /* +1 for ':'*/
67 64
 				}
68 65
 		}
69 66
 		memcpy(new_buf+offset, orig+s_offset, 
70 67
 								size);
71 68
 		offset+=size;
72 69
 		s_offset+=size;
73
-		printf("4\n");
74 70
 		memcpy(new_buf+offset, received_buf, received_len);
75
-		printf("5\n");
76 71
 		offset+=received_len;
77 72
 	}
78 73
  	/* copy the rest of the msg */
79 74
  	memcpy(new_buf+offset, orig+s_offset, len-s_offset);
80
-	printf("6\n");
81 75
 	new_buf[new_len]=0;
82 76
 
83 77
 	 /* send it! */
84
-	 printf("Sending:\n%s.\n", new_buf);
85
-	 
78
+	printf("Sending:\n%s.\n", new_buf);
79
+	printf("orig. len=%d, new_len=%d, via_len=%d, received_len=%d\n",
80
+			len, new_len, via_len, received_len);
81
+
82
+	to.sin_family = AF_INET;
83
+	to.sin_port = (re->port)?htons(re->port):htons(SIP_PORT);
84
+	/* if error try next ip address if possible */
85
+	if (re->ok==0){
86
+		if (re->host.h_addr_list[re->current_addr_idx+1])
87
+			re->current_addr_idx++;
88
+		re->ok=1;
89
+	}
90
+	/* ? not 64bit clean?*/
91
+	to.sin_addr.s_addr=*((long*)re->host.h_addr_list[re->current_addr_idx]);
92
+
93
+	re->tx++;
94
+	re->tx_bytes+=new_len;
95
+	if (udp_send(new_buf, new_len, &to, sizeof(to))==-1){
96
+			re->errors++;
97
+			re->ok=0;
98
+			goto error;
99
+	}
100
+
101
+	free(new_buf);
86 102
 	return 0;
87 103
 error:
104
+	free(new_buf);
105
+error1:
88 106
 	return -1;
89 107
 
90 108
 }
... ...
@@ -101,37 +121,51 @@ int forward_reply(char * orig, char* buf,
101 101
 	unsigned int new_len, via_len;
102 102
 	char* new_buf;
103 103
 	int offset, s_offset, size;
104
+	struct hostent* he;
105
+	struct sockaddr_in to;
104 106
 
105 107
 
106
-	/* we must remove first via */
108
+	/* we must remove the first via */
107 109
 	via_len=msg->via1.size;
108 110
 	size=msg->via1.hdr-buf;
109 111
 	if (msg->via1.next){
110
-		via_len-=strlen(msg->via1.hdr)+1; /* +1 from ':' */
112
+		/* keep hdr =substract hdr size +1 (hdr':') and add
113
+		 */
114
+		via_len-=strlen(msg->via1.hdr)+1;
111 115
 		size+=strlen(msg->via1.hdr)+1;
112 116
 	}
113 117
 	new_len=len-size;
114
-	printf("r1\n");
115 118
 	new_buf=(char*)malloc(new_len);
116 119
 	if (new_buf==0){
117 120
 		DPrint("ERROR: forward_reply: out of memory\n");
118 121
 		goto error;
119 122
 	}
120
-	printf("r2\n");
121 123
 	memcpy(new_buf, orig, size);
122 124
 	offset=size;
123 125
 	s_offset=size+via_len;
124
-	printf("r3\n");
125 126
 	memcpy(new_buf+offset,orig+s_offset, len-s_offset);
126
-	printf("r4\n");
127 127
 	 /* send it! */
128 128
 	printf("Sending: to %s:%d, \n%s.\n",
129 129
 			msg->via2.host, 
130 130
 			(unsigned short)msg->via2.port,
131 131
 			new_buf);
132
+	/* fork? gethostbyname will probably block... */
133
+	he=gethostbyname(msg->via2.host);
134
+	if (he==0){
135
+		DPrint("ERROR:forward_reply:gethostbyname failure\n");
136
+		goto error;
137
+	}
138
+	to.sin_family = AF_INET;
139
+	to.sin_port = (msg->via2.port)?htons(msg->via2.port):htons(SIP_PORT);
140
+	to.sin_addr.s_addr=*((long*)he->h_addr_list[0]);
141
+	
142
+	if (udp_send(new_buf,new_len, &to, sizeof(to))==-1)
143
+		goto error;
132 144
 	
145
+	free(new_buf);
133 146
 	return 0;
134 147
 
135 148
 error:
149
+	if (new_buf) free(new_buf);
136 150
 	return -1;
137 151
 }
... ...
@@ -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 27
 		printf("-------------------------\n");
28 28
 	}
29 29
 }
30
+*/
30 31
 
32
+#define NAME "dorian.fokus.gmd.de"
31 33
 
32 34
 
33 35
 int main(int argc, char** argv)
... ...
@@ -35,12 +39,29 @@ int main(int argc, char** argv)
35 35
 
36 36
 	char * cfg_file;
37 37
 	FILE* cfg_stream;
38
+	struct hostent* he;
38 39
 
39 40
 	cfg_file=CFG_FILE;
40 41
 	
41 42
 	/* process command line (get port no, cfg. file path etc) */
42 43
 	/* ...*/
43 44
 
45
+	our_port=SIP_PORT;
46
+	our_name=NAME;
47
+	/* get ip */
48
+	he=gethostbyname(our_name);
49
+	if (he==0){
50
+		DPrint("ERROR: could not resolve %s\n", our_name);
51
+		goto error;
52
+	}
53
+	our_address=*((long*)he->h_addr_list[0]);
54
+	printf("Listening on %s[%x]:%d\n",our_name,
55
+				(unsigned long)our_address,
56
+				(unsigned short)our_port);
57
+		
58
+	
59
+	
60
+
44 61
 	/* load config file or die */
45 62
 	cfg_stream=fopen (cfg_file, "r");
46 63
 	if (cfg_stream==0){
... ...
@@ -57,12 +78,12 @@ int main(int argc, char** argv)
57 57
 	print_rl();
58 58
 
59 59
 
60
-
60
+	/* init_daemon? */
61
+	if (udp_init(our_address,our_port)==-1) goto error;
61 62
 	/* start/init other processes/threads ? */
62 63
 
63 64
 	/* receive loop */
64
-
65
-	receive_stdin_loop();
65
+	udp_rcv_loop();
66 66
 
67 67
 
68 68
 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 423
 			DPrint("ERROR: parsing via body: %s\n", second_via);
424 424
 			goto error;
425 425
 		}
426
-		vb2.size=tmp-second_via;
426
+		vb2.size=tmp-second_via; 
427
+		if (vb2.next==0) vb2.size+=1; /* +1 from trailing lf */
427 428
 		if (vb2.hdr) vb2.size+=second_via-vb2.hdr;
428 429
 	}
429 430
 	
... ...
@@ -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 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+#include <sys/types.h>
5
+#include <sys/socket.h>
6
+#include <netinet/in.h>
7
+#include <errno.h>
8
+
9
+
10
+#include "udp_server.h"
11
+#include "config.h"
12
+#include "dprint.h"
13
+
14
+
15
+int udp_sock;
16
+
17
+char* our_name;
18
+unsigned long our_address;
19
+unsigned short our_port;
20
+
21
+
22
+
23
+int udp_init(unsigned long ip, unsigned short port)
24
+{
25
+	struct sockaddr_in addr;
26
+
27
+	addr.sin_family=AF_INET;
28
+	addr.sin_port=htons(port);
29
+	addr.sin_addr.s_addr=ip;
30
+
31
+	udp_sock = socket(PF_INET, SOCK_DGRAM, 0);
32
+	if (udp_sock==-1){
33
+		DPrint("ERROR: udp_init: socket: %s\n", strerror());
34
+		goto error;
35
+	}
36
+
37
+	if (bind(udp_sock, (struct sockaddr*) &addr, sizeof(addr))==-1){
38
+		DPrint("ERROR: udp_init: socket: %s\n", strerror());
39
+		goto error;
40
+	}
41
+
42
+	/* set sock opts? */
43
+
44
+	return 0;
45
+
46
+error:
47
+	return -1;
48
+}
49
+
50
+
51
+
52
+int udp_rcv_loop()
53
+{
54
+	int len;
55
+	char buf[BUF_SIZE+1];
56
+	struct sockaddr* from;
57
+	int fromlen;
58
+
59
+	from=(struct sockaddr*) malloc(sizeof(struct sockaddr));
60
+	if (from==0){
61
+		DPrint("ERROR: udp_rcv_loop: out of memory\n");
62
+		goto error;
63
+	}
64
+
65
+	for(;;){
66
+		fromlen=sizeof(*from);
67
+		len=recvfrom(udp_sock, buf, BUF_SIZE, 0, from, &fromlen);
68
+		if (len==-1){
69
+			DPrint("ERROR: udp_rcv_loop:recvfrom: %s\n", strerror());
70
+			if (errno==EINTR)	goto skip;
71
+			else goto error;
72
+		}
73
+		/*debugging, make print* msg work */
74
+		buf[len+1]=0;
75
+
76
+		receive_msg(buf, len, from, fromlen);
77
+
78
+	skip: /* do other stuff */
79
+		
80
+	}
81
+
82
+	return 0;
83
+	
84
+error:
85
+	return -1;
86
+}
87
+
88
+
89
+
90
+/* which socket to use? main socket or new one? */
91
+int udp_send(char *buf, int len, struct sockaddr*  to, int tolen)
92
+{
93
+
94
+	int n;
95
+again:
96
+	n=sendto(udp_sock, buf, len, 0, to, tolen);
97
+	if (n==-1){
98
+		DPrint("ERROR: udp_send: sendto: %s\n", strerror());
99
+		if (errno==EINTR) goto again;
100
+	}
101
+	return n;
102
+}
0 103
new file mode 100644
... ...
@@ -0,0 +1,20 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+#ifndef udp_server_h
5
+#define udp_server_h
6
+
7
+
8
+
9
+extern int udp_sock;
10
+
11
+extern char* our_name;
12
+extern unsigned long  our_address;
13
+extern unsigned short our_port;
14
+
15
+int udp_init(unsigned long ip, unsigned short port);
16
+int udp_rcv_loop();
17
+
18
+
19
+#endif