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 111
 REPLY_TO_VIA reply_to_via
112 112
 USER		"user"|"uid"
113 113
 GROUP		"group"|"gid"
114
+MHOMED		mhomed
114 115
 
115 116
 LOADMODULE	loadmodule
116 117
 MODPARAM        modparam
... ...
@@ -210,6 +238,7 @@ EAT_ABLE	[\ \t\b\r]
210 210
 <INITIAL>{SIP_WARNING}	{ count(); yylval.strval=yytext; return SIP_WARNING; }
211 211
 <INITIAL>{USER}		{ count(); yylval.strval=yytext; return USER; }
212 212
 <INITIAL>{GROUP}	{ count(); yylval.strval=yytext; return GROUP; }
213
+<INITIAL>{MHOMED}	{ count(); yylval.strval=yytext; return MHOMED; }
213 214
 <INITIAL>{FIFO}	{ count(); yylval.strval=yytext; return FIFO; }
214 215
 <INITIAL>{FIFO_MODE}	{ count(); yylval.strval=yytext; return FIFO_MODE; }
215 216
 <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 122
 %token MAXBUFFER
123 123
 %token USER
124 124
 %token GROUP
125
+%token MHOMED
125 126
 
126 127
 
127 128
 
... ...
@@ -288,6 +318,8 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
288 288
 		| GROUP EQUAL STRING     { group=$3; }
289 289
 		| GROUP EQUAL ID         { group=$3; }
290 290
 		| GROUP EQUAL error      { yyerror("string value expected"); }
291
+		| MHOMED EQUAL NUMBER { mhomed=$3; }
292
+		| MHOMED EQUAL error { yyerror("boolean value expected"); }
291 293
 		| SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
292 294
 		| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
293 295
 		| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
... ...
@@ -3140,6 +3140,28 @@ if (to me):
3140 3140
 		<qandaentry>
3141 3141
 		    <question>
3142 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>
3162
+		<qandaentry>
3163
+		    <question>
3164
+			<para>
3143 3165
 			    I receive "ERROR: t_newtran: transaction already in process" in my logs.
3144 3166
 			</para>
3145 3167
 		    </question>
... ...
@@ -3530,7 +3552,7 @@ SIP_HF_CONTACT=<sip:123.20.128.35:9315>
3530 3530
 		to <filename moreinfo="none">/tmp/</filename> path), to which
3531 3531
 		a reply should be printed. The first request line may be
3532 3532
 		followed by additional lines with command-specific 
3533
-		parameters. For example, the <command moreinfo="none">t_uac</command>
3533
+		parameters. For example, the <command moreinfo="none">t_uac_dlg</command>
3534 3534
 		FIFO command for initiating a transaction allows 
3535 3535
 		to pass additional header fields and message body to
3536 3536
 		a newly created transaction. Each request is terminated by
... ...
@@ -3632,7 +3654,7 @@ print
3632 3632
 		(instant message)
3633 3633
 		from a PHP script via the FIFO server. This example
3634 3634
 		uses FIFO command 
3635
-		<command moreinfo="none">t_uac</command>. The command
3635
+		<command moreinfo="none">t_uac_dlg</command>. The command
3636 3636
 		is followed by parameters: header fields and 
3637 3637
 		message body. The same FIFO command can be used from
3638 3638
 		other environments to send instant messages too. The
... ...
@@ -3646,18 +3668,24 @@ print
3646 3646
 # call this script to send an instant message; script parameters
3647 3647
 # will be displayed in message body
3648 3648
 #
3649
+# paremeters mean: message type, request-URI, outbound server is
3650
+# left blank ("."), required header fields From and To follow,
3651
+# then optional header fields terminated by dot and optional
3652
+# dot-terminated body
3649 3653
 
3650 3654
 cat &gt; /tmp/ser_fifo &lt;&lt;EOF
3651
-:t_uac_from:hh
3655
+:t_uac_dlg:hh
3652 3656
 NOTIFY
3653
-sip:originator@foo.bar
3654 3657
 sip:receiver@127.0.0.1
3658
+.
3659
+From: sip:originator@foo.bar
3660
+To: sip:receiver@127.0.0.1
3655 3661
 foo: bar_special_header
3656 3662
 x: y
3657 3663
 p_header: p_value
3658 3664
 Contact: &lt;sip:devnull@192.168.0.100:9&gt;
3659 3665
 Content-Type: text/plain; charset=UTF-8
3660
-
3666
+.
3661 3667
 Hello world!!!! $@
3662 3668
 .
3663 3669
 EOF
... ...
@@ -4053,8 +4081,11 @@ Domain Registered Expired
4053 4053
 		</listitem>
4054 4054
 		<listitem>
4055 4055
 		    <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.
4056
+			<varname>reply_to_via</varname> - A hint to reply modules
4057
+			whether they should send reply
4058
+			to IP advertised in Via.
4059
+			Turned off by default, which means that replies are
4060
+			sent to IP address from which requests came from. 
4058 4061
 		    </para>
4059 4062
 		</listitem>
4060 4063
 		<listitem>
... ...
@@ -4069,6 +4100,13 @@ Domain Registered Expired
4069 4069
 		</listitem>
4070 4070
 		<listitem>
4071 4071
 		    <para>
4072
+			<varname>mhomed</varname> -- enable calculation of 
4073
+			outbound interface; useful on multihomed servers,
4074
+			ser <link linkend="mhomed"></link>.
4075
+		    </para>
4076
+		</listitem>
4077
+		<listitem>
4078
+		    <para>
4072 4079
 			<varname>loadmodule</varname> - Specifies a module to be loaded (for example "/usr/lib/ser/modules/tm.so")
4073 4080
 		    </para>
4074 4081
 		</listitem>
... ...
@@ -5094,12 +5132,19 @@ if (len_gt(1024)) {
5094 5094
 			    <entry>print occupation of transaction table (mainly for debugging)</entry>
5095 5095
 			</row>
5096 5096
 			<row>
5097
-			    <entry>t_uac_from</entry>
5097
+			    <entry>t_uac_dlg</entry>
5098 5098
 			    <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>
5099
+			    <entry>method, request URI, outbound URI (if none, empty line with a single dot),
5100
+					dot-line-terminated header fields, optionaly dot-line terminated message
5101
+					body. 
5102
+				</entry>
5103
+					
5104
+			    <entry>initiate a transaction.
5105
+					From and To header fields must be present in header field list,
5106
+					so does Content-Type if body is present. If CSeq, CallId and From-tag
5107
+					are not present, ephemeral values are generated. Content_length is
5108
+					calculated automatically if body present.
5109
+				</entry>
5103 5110
 			</row>
5104 5111
 			<row>
5105 5112
 			    <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 61
 #include <dmalloc.h>
62 62
 #endif
63 63
 
64
+/* return a socket_info_pointer to the sending socket; as opposed to
65
+ * get_send_socket, which returns process's default socket, get_out_socket
66
+ * attempts to determine the outbound interface which will be used;
67
+ * it creates a temporary connected socket to determine it; it will
68
+ * be very likely noticeably slower, but it can deal better with
69
+ * multihomed hosts
70
+ */
71
+struct socket_info* get_out_socket(union sockaddr_union* to, int proto)
72
+{
73
+	int temp_sock;
74
+	socklen_t len;
75
+	int r;
76
+	union sockaddr_union from; 
77
+
78
+	if (proto!=PROTO_UDP) {
79
+		LOG(L_CRIT, "BUG: get_out_socket can only be called for UDP\n");
80
+		return 0;
81
+	}
82
+
83
+	r=-1;
84
+	temp_sock=socket(to->s.sa_family, SOCK_DGRAM, 0 );
85
+	if (temp_sock==-1) {
86
+		LOG(L_ERR, "ERROR: get_out_socket: socket() failed: %s\n",
87
+				strerror(errno));
88
+		return 0;
89
+	}
90
+	if (connect(temp_sock, &to->s, sockaddru_len(*to))==-1) {
91
+		LOG(L_ERR, "ERROR: get_out_socket: connect failed: %s\n",
92
+				strerror(errno));
93
+		goto error;
94
+	}
95
+	len=sockaddru_len(from);
96
+	if (getsockname(temp_sock, &from.s, &len)==-1) {
97
+		LOG(L_ERR, "ERROR: get_out_socket: getsockname failed: %s\n",
98
+				strerror(errno));
99
+		goto error;
100
+	}
101
+	for (r=0; r<sock_no; r++) {
102
+		switch(from.s.sa_family) {
103
+			case AF_INET:	
104
+						if (sock_info[r].address.af!=AF_INET)
105
+								continue;
106
+						if (memcmp(&sock_info[r].address.u,
107
+								&from.sin.sin_addr, 
108
+								sock_info[r].address.len)==0)
109
+							goto error; /* it is actually success */
110
+						break;
111
+			case AF_INET6:	
112
+						if (sock_info[r].address.af!=AF_INET6)
113
+								continue;
114
+						if (memcmp(&sock_info[r].address.u,
115
+								&from.sin6.sin6_addr, len)==0)
116
+							goto error;
117
+						continue;
118
+			default:	LOG(L_ERR, "ERROR: get_out_socket: "
119
+									"unknown family: %d\n",
120
+									from.s.sa_family);
121
+						r=-1;
122
+						goto error;
123
+		}
124
+	}
125
+	LOG(L_ERR, "ERROR: get_out_socket: no socket found\n");
126
+	r=-1;
127
+error:
128
+	close(temp_sock);
129
+	DBG("DEBUG: get_out_socket: socket determined: %d\n", r );
130
+	return r==-1? 0: &sock_info[r];
131
+}
132
+
64 133
 
65 134
 
66 135
 /* returns a socket_info pointer to the sending socket or 0 on error
... ...
@@ -69,7 +144,9 @@
69 69
 struct socket_info* get_send_socket(union sockaddr_union* to, int proto)
70 70
 {
71 71
 	struct socket_info* send_sock;
72
-	
72
+
73
+	if (mhomed && proto==PROTO_UDP) return get_out_socket(to, proto);
74
+
73 75
 	send_sock=0;
74 76
 	/* check if we need to change the socket (different address families -
75 77
 	 * 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 263
    be default yes, good for trouble-shooting
264 264
 */
265 265
 int server_signature=1;
266
+/* should ser try to locate outbound interface on multihomed
267
+ * host? by default not -- too expensive
268
+ */
269
+int mhomed=0;
266 270
 /* use dns and/or rdns or to see if we need to add 
267 271
    a ;received=x.x.x.x to via: */
268 272
 int received_dns = 0;