Browse code

determination of outbound interace introduced (get_out_socket)

Jiri Kuthan authored on 23/01/2003 12:27:50
Showing 8 changed files
... ...
@@ -2,6 +2,33 @@
2 2
  * $Id$
3 3
  *
4 4
  * scanner for cfg files
5
+ *
6
+ * Copyright (C) 2001-2003 Fhg Fokus
7
+ *
8
+ * This file is part of ser, a free SIP server.
9
+ *
10
+ * ser is free software; you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation; either version 2 of the License, or
13
+ * (at your option) any later version
14
+ *
15
+ * For a license to use the ser software under conditions
16
+ * other than those described here, or to purchase support for this
17
+ * software, please contact iptel.org by e-mail at the following addresses:
18
+ *    info@iptel.org
19
+ *
20
+ * ser is distributed in the hope that it will be useful,
21
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
+ * GNU General Public License for more details.
24
+ *
25
+ * You should have received a copy of the GNU General Public License 
26
+ * along with this program; if not, write to the Free Software 
27
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28
+ *
29
+ * History:
30
+ * -------
31
+ * 2001-01-23 mhomed added (jiri)
5 32
  */
6 33
 
7 34
 
... ...
@@ -111,6 +138,7 @@ SERVER_SIGNATURE server_signature
111 138
 REPLY_TO_VIA reply_to_via
112 139
 USER		"user"|"uid"
113 140
 GROUP		"group"|"gid"
141
+MHOMED		mhomed
114 142
 
115 143
 LOADMODULE	loadmodule
116 144
 MODPARAM        modparam
... ...
@@ -210,6 +238,7 @@ EAT_ABLE	[\ \t\b\r]
210 238
 <INITIAL>{SIP_WARNING}	{ count(); yylval.strval=yytext; return SIP_WARNING; }
211 239
 <INITIAL>{USER}		{ count(); yylval.strval=yytext; return USER; }
212 240
 <INITIAL>{GROUP}	{ count(); yylval.strval=yytext; return GROUP; }
241
+<INITIAL>{MHOMED}	{ count(); yylval.strval=yytext; return MHOMED; }
213 242
 <INITIAL>{FIFO}	{ count(); yylval.strval=yytext; return FIFO; }
214 243
 <INITIAL>{FIFO_MODE}	{ count(); yylval.strval=yytext; return FIFO_MODE; }
215 244
 <INITIAL>{SERVER_SIGNATURE}	{ count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
... ...
@@ -2,6 +2,35 @@
2 2
  * $Id$
3 3
  *
4 4
  *  cfg grammar
5
+ *
6
+ * Copyright (C) 2001-2003 Fhg Fokus
7
+ *
8
+ * This file is part of ser, a free SIP server.
9
+ *
10
+ * ser is free software; you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation; either version 2 of the License, or
13
+ * (at your option) any later version
14
+ *
15
+ * For a license to use the ser software under conditions
16
+ * other than those described here, or to purchase support for this
17
+ * software, please contact iptel.org by e-mail at the following addresses:
18
+ *    info@iptel.org
19
+ *
20
+ * ser is distributed in the hope that it will be useful,
21
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
+ * GNU General Public License for more details.
24
+ *
25
+ * You should have received a copy of the GNU General Public License 
26
+ * along with this program; if not, write to the Free Software 
27
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28
+ *
29
+ * History:
30
+ * ---------
31
+ * 2003-01-23 mhomed added (jiri)
32
+ */
33
+
5 34
  */
6 35
 
7 36
 %{
... ...
@@ -122,6 +151,7 @@ struct id_list* lst_tmp;
122 151
 %token MAXBUFFER
123 152
 %token USER
124 153
 %token GROUP
154
+%token MHOMED
125 155
 
126 156
 
127 157
 
... ...
@@ -288,6 +318,8 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
288 318
 		| GROUP EQUAL STRING     { group=$3; }
289 319
 		| GROUP EQUAL ID         { group=$3; }
290 320
 		| GROUP EQUAL error      { yyerror("string value expected"); }
321
+		| MHOMED EQUAL NUMBER { mhomed=$3; }
322
+		| MHOMED EQUAL error { yyerror("boolean value expected"); }
291 323
 		| SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
292 324
 		| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
293 325
 		| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
... ...
@@ -3137,6 +3137,28 @@ if (to me):
3137 3137
 			</para>
3138 3138
 		    </answer>
3139 3139
 		</qandaentry>
3140
+		<qandaentry>
3141
+		    <question>
3142
+			<para>
3143
+			    On a multihomed host, forwarded messages carry other 
3144
+			    interface in Via than used for sending, or messages 
3145
+			    are not sent and an error log is issued "invalid 
3146
+			    sendtoparameters one possible reason is the server 
3147
+			    is bound to localhost".
3148
+			</para>
3149
+		    </question>
3150
+		    <answer>
3151
+			<anchor id="mhomed">
3152
+			<para>
3153
+			    Set the configuration option <varname>mhome</varname>
3154
+			    to "1". <application moreinfo="none">ser</application>
3155
+			    will then attempt to calculate the correct interface.
3156
+			    It's not done by default as it degrades performance
3157
+			    on single-homed hosts or multi-homed hosts that are
3158
+			    not set-up as routers.
3159
+			</para>
3160
+		    </answer>
3161
+		</qandaentry>
3140 3162
 		<qandaentry>
3141 3163
 		    <question>
3142 3164
 			<para>
... ...
@@ -3530,7 +3552,7 @@ SIP_HF_CONTACT=<sip:123.20.128.35:9315>
3530 3552
 		to <filename moreinfo="none">/tmp/</filename> path), to which
3531 3553
 		a reply should be printed. The first request line may be
3532 3554
 		followed by additional lines with command-specific 
3533
-		parameters. For example, the <command moreinfo="none">t_uac</command>
3555
+		parameters. For example, the <command moreinfo="none">t_uac_dlg</command>
3534 3556
 		FIFO command for initiating a transaction allows 
3535 3557
 		to pass additional header fields and message body to
3536 3558
 		a newly created transaction. Each request is terminated by
... ...
@@ -3632,7 +3654,7 @@ print
3632 3654
 		(instant message)
3633 3655
 		from a PHP script via the FIFO server. This example
3634 3656
 		uses FIFO command 
3635
-		<command moreinfo="none">t_uac</command>. The command
3657
+		<command moreinfo="none">t_uac_dlg</command>. The command
3636 3658
 		is followed by parameters: header fields and 
3637 3659
 		message body. The same FIFO command can be used from
3638 3660
 		other environments to send instant messages too. The
... ...
@@ -3646,18 +3668,24 @@ print
3646 3668
 # call this script to send an instant message; script parameters
3647 3669
 # will be displayed in message body
3648 3670
 #
3671
+# paremeters mean: message type, request-URI, outbound server is
3672
+# left blank ("."), required header fields From and To follow,
3673
+# then optional header fields terminated by dot and optional
3674
+# dot-terminated body
3649 3675
 
3650 3676
 cat &gt; /tmp/ser_fifo &lt;&lt;EOF
3651
-:t_uac_from:hh
3677
+:t_uac_dlg:hh
3652 3678
 NOTIFY
3653
-sip:originator@foo.bar
3654 3679
 sip:receiver@127.0.0.1
3680
+.
3681
+From: sip:originator@foo.bar
3682
+To: sip:receiver@127.0.0.1
3655 3683
 foo: bar_special_header
3656 3684
 x: y
3657 3685
 p_header: p_value
3658 3686
 Contact: &lt;sip:devnull@192.168.0.100:9&gt;
3659 3687
 Content-Type: text/plain; charset=UTF-8
3660
-
3688
+.
3661 3689
 Hello world!!!! $@
3662 3690
 .
3663 3691
 EOF
... ...
@@ -4053,8 +4081,11 @@ Domain Registered Expired
4053 4081
 		</listitem>
4054 4082
 		<listitem>
4055 4083
 		    <para>
4056
-			<varname>reply_to_via</varname> - A hint to reply modules whether they should send reply
4057
-			to IP advertised in Via or IP from which a request came.
4084
+			<varname>reply_to_via</varname> - A hint to reply modules
4085
+			whether they should send reply
4086
+			to IP advertised in Via.
4087
+			Turned off by default, which means that replies are
4088
+			sent to IP address from which requests came from. 
4058 4089
 		    </para>
4059 4090
 		</listitem>
4060 4091
 		<listitem>
... ...
@@ -4067,6 +4098,13 @@ Domain Registered Expired
4067 4098
 			<varname>group | gid</varname> - gid to be used by the server.
4068 4099
 		    </para>
4069 4100
 		</listitem>
4101
+		<listitem>
4102
+		    <para>
4103
+			<varname>mhomed</varname> -- enable calculation of 
4104
+			outbound interface; useful on multihomed servers,
4105
+			ser <link linkend="mhomed"></link>.
4106
+		    </para>
4107
+		</listitem>
4070 4108
 		<listitem>
4071 4109
 		    <para>
4072 4110
 			<varname>loadmodule</varname> - Specifies a module to be loaded (for example "/usr/lib/ser/modules/tm.so")
... ...
@@ -5094,12 +5132,19 @@ if (len_gt(1024)) {
5094 5132
 			    <entry>print occupation of transaction table (mainly for debugging)</entry>
5095 5133
 			</row>
5096 5134
 			<row>
5097
-			    <entry>t_uac_from</entry>
5135
+			    <entry>t_uac_dlg</entry>
5098 5136
 			    <entry>tm</entry>
5099
-			    <entry>method, sender's URI, destination URI, optional header fields
5100
-			    terminated by empty line, message body terminated by a line with
5101
-			    a single dot</entry>
5102
-			    <entry>initiate a transaction</entry>
5137
+			    <entry>method, request URI, outbound URI (if none, empty line with a single dot),
5138
+					dot-line-terminated header fields, optionaly dot-line terminated message
5139
+					body. 
5140
+				</entry>
5141
+					
5142
+			    <entry>initiate a transaction.
5143
+					From and To header fields must be present in header field list,
5144
+					so does Content-Type if body is present. If CSeq, CallId and From-tag
5145
+					are not present, ephemeral values are generated. Content_length is
5146
+					calculated automatically if body present.
5147
+				</entry>
5103 5148
 			</row>
5104 5149
 			<row>
5105 5150
 			    <entry>ul_stats</entry>
... ...
@@ -31,12 +31,14 @@ if (!$fifo_handle) {
31 31
 }
32 32
 
33 33
 /* construct FIFO command */
34
-$fifo_cmd=":t_uac:".$myfilename."\n".
35
-    "MESSAGE\n".$sip_address."\n".
34
+$fifo_cmd=":t_uac_dlg:".$myfilename."\n".
35
+    "MESSAGE\n".$sip_address."\n.\n".
36
+	"From: sip:sender@foo.bar\n".
37
+	"To: ".$sip_address."\n".
36 38
     "p-version: ".$signature."\n".
37 39
     "Contact: ".$web_contact."\n".
38
-    "Content-Type: text/plain; charset=UTF-8\n\n".
39
-    $instant_message."\n.\n\n";
40
+    "Content-Type: text/plain; charset=UTF-8\n.\n".
41
+    $instant_message."\n.\n";
40 42
 
41 43
 /* create fifo for replies */
42 44
 system("mkfifo -m 666 ".$mypath );
... ...
@@ -23,6 +23,12 @@
23 23
  * You should have received a copy of the GNU General Public License 
24 24
  * along with this program; if not, write to the Free Software 
25 25
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ *
27
+ * History:
28
+ * -------
29
+ * 2001-01-23 support for determination of outbound interface added :
30
+ *            get_out_socket (jiri)
31
+ *
26 32
  */
27 33
 
28 34
 
... ...
@@ -61,6 +67,75 @@
61 67
 #include <dmalloc.h>
62 68
 #endif
63 69
 
70
+/* return a socket_info_pointer to the sending socket; as opposed to
71
+ * get_send_socket, which returns process's default socket, get_out_socket
72
+ * attempts to determine the outbound interface which will be used;
73
+ * it creates a temporary connected socket to determine it; it will
74
+ * be very likely noticeably slower, but it can deal better with
75
+ * multihomed hosts
76
+ */
77
+struct socket_info* get_out_socket(union sockaddr_union* to, int proto)
78
+{
79
+	int temp_sock;
80
+	socklen_t len;
81
+	int r;
82
+	union sockaddr_union from; 
83
+
84
+	if (proto!=PROTO_UDP) {
85
+		LOG(L_CRIT, "BUG: get_out_socket can only be called for UDP\n");
86
+		return 0;
87
+	}
88
+
89
+	r=-1;
90
+	temp_sock=socket(to->s.sa_family, SOCK_DGRAM, 0 );
91
+	if (temp_sock==-1) {
92
+		LOG(L_ERR, "ERROR: get_out_socket: socket() failed: %s\n",
93
+				strerror(errno));
94
+		return 0;
95
+	}
96
+	if (connect(temp_sock, &to->s, sockaddru_len(*to))==-1) {
97
+		LOG(L_ERR, "ERROR: get_out_socket: connect failed: %s\n",
98
+				strerror(errno));
99
+		goto error;
100
+	}
101
+	len=sockaddru_len(from);
102
+	if (getsockname(temp_sock, &from.s, &len)==-1) {
103
+		LOG(L_ERR, "ERROR: get_out_socket: getsockname failed: %s\n",
104
+				strerror(errno));
105
+		goto error;
106
+	}
107
+	for (r=0; r<sock_no; r++) {
108
+		switch(from.s.sa_family) {
109
+			case AF_INET:	
110
+						if (sock_info[r].address.af!=AF_INET)
111
+								continue;
112
+						if (memcmp(&sock_info[r].address.u,
113
+								&from.sin.sin_addr, 
114
+								sock_info[r].address.len)==0)
115
+							goto error; /* it is actually success */
116
+						break;
117
+			case AF_INET6:	
118
+						if (sock_info[r].address.af!=AF_INET6)
119
+								continue;
120
+						if (memcmp(&sock_info[r].address.u,
121
+								&from.sin6.sin6_addr, len)==0)
122
+							goto error;
123
+						continue;
124
+			default:	LOG(L_ERR, "ERROR: get_out_socket: "
125
+									"unknown family: %d\n",
126
+									from.s.sa_family);
127
+						r=-1;
128
+						goto error;
129
+		}
130
+	}
131
+	LOG(L_ERR, "ERROR: get_out_socket: no socket found\n");
132
+	r=-1;
133
+error:
134
+	close(temp_sock);
135
+	DBG("DEBUG: get_out_socket: socket determined: %d\n", r );
136
+	return r==-1? 0: &sock_info[r];
137
+}
138
+
64 139
 
65 140
 
66 141
 /* returns a socket_info pointer to the sending socket or 0 on error
... ...
@@ -69,7 +144,9 @@
69 144
 struct socket_info* get_send_socket(union sockaddr_union* to, int proto)
70 145
 {
71 146
 	struct socket_info* send_sock;
72
-	
147
+
148
+	if (mhomed && proto==PROTO_UDP) return get_out_socket(to, proto);
149
+
73 150
 	send_sock=0;
74 151
 	/* check if we need to change the socket (different address families -
75 152
 	 * eg: ipv4 -> ipv6 or ipv6 -> ipv4) */
... ...
@@ -37,6 +37,7 @@
37 37
 
38 38
 
39 39
 struct socket_info* get_send_socket(union sockaddr_union* su, int proto);
40
+struct socket_info* get_out_socket(union sockaddr_union* to, int proto);
40 41
 int check_self(str* host, unsigned short port);
41 42
 int forward_request( struct sip_msg* msg,  struct proxy_l* p, int proto);
42 43
 int update_sock_struct_from_via( union sockaddr_union* to,
... ...
@@ -113,4 +113,7 @@ extern int is_main;
113 113
 /* debugging level for dumping memory status */
114 114
 extern int memlog;
115 115
 
116
+/* looking up outbound interface ? */
117
+extern int mhomed;
118
+
116 119
 #endif
... ...
@@ -23,6 +23,11 @@
23 23
  * You should have received a copy of the GNU General Public License 
24 24
  * along with this program; if not, write to the Free Software 
25 25
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ *
27
+ * History:
28
+ * -------
29
+ * 2001-01-23 mhomed added (jiri)
30
+ *
26 31
  */
27 32
 
28 33
 
... ...
@@ -263,6 +268,10 @@ int sip_warning = 1;
263 268
    be default yes, good for trouble-shooting
264 269
 */
265 270
 int server_signature=1;
271
+/* should ser try to locate outbound interface on multihomed
272
+ * host? by default not -- too expensive
273
+ */
274
+int mhomed=0;
266 275
 /* use dns and/or rdns or to see if we need to add 
267 276
    a ;received=x.x.x.x to via: */
268 277
 int received_dns = 0;