Browse code

Merge pull request #45 from grumvalski/cdp_src_addr

modules/cdp: added src_addr parameter in peer definition

Daniel-Constantin Mierla authored on 26/03/2015 22:34:26
Showing 7 changed files
... ...
@@ -54,6 +54,7 @@ typedef struct{
54 54
 	str fqdn;	/**< FQDN of the peer */
55 55
 	str realm;	/**< Realm of the peer */
56 56
 	int port;	/**< TCP port of the peer; the Diameter uri is then aaa://fqdn:port. */
57
+    str src_addr; /**< IP address used to connect to the peer */
57 58
 } peer_config;
58 59
 
59 60
 
... ...
@@ -54,7 +54,7 @@
54 54
 		a dedicated receiver process will be forked. All other unkwnown peers will share a single
55 55
 		receiver.
56 56
 	-->
57
-	<Peer FQDN="hss.open-ims.test" Realm="open-ims.test" port="3868"/>
57
+	<Peer FQDN="hss.open-ims.test" Realm="open-ims.test" port="3868" src_addr="192.168.1.1"/>
58 58
 
59 59
 	<!--
60 60
 		Definition of incoming connection acceptors. If no bind is specified, the acceptor will bind
... ...
@@ -331,7 +331,12 @@ dp_config* parse_dp_config(xmlDocPtr doc)
331 331
 				x->peers[x->peers_cnt].port = atoi((char*)xc);
332 332
 				xmlFree(xc);
333 333
 			}
334
-			x->peers_cnt++;		
334
+			xc = xmlGetProp(child,(xmlChar*)"src_addr");
335
+			if (xc){
336
+				quote_trim_dup(&(x->peers[x->peers_cnt].src_addr),(char*)xc);
337
+				xmlFree(xc);
338
+			}
339
+			x->peers_cnt++;
335 340
 		}
336 341
 		else if (xmlStrlen(child->name)==8 && strncasecmp((char*)child->name,"Acceptor",8)==0){
337 342
 			//Acceptor
... ...
@@ -459,7 +464,7 @@ dp_config* parse_dp_config(xmlDocPtr doc)
459 459
 												rei->next = re;
460 460
 												break;
461 461
 											}
462
-										} 					
462
+										}					
463 463
 								}
464 464
 							}
465 465
 						}
... ...
@@ -56,7 +56,7 @@
56 56
  * @param port - port of the peer to connect to
57 57
  * @returns the new peer* if ok, NULL on error
58 58
  */
59
-peer* new_peer(str fqdn,str realm,int port)
59
+peer* new_peer(str fqdn,str realm,int port,str src_addr)
60 60
 {
61 61
 	peer *x;
62 62
 	x = shm_malloc(sizeof(peer));
... ...
@@ -69,6 +69,8 @@ peer* new_peer(str fqdn,str realm,int port)
69 69
 	if (!x->fqdn.s) goto error;	
70 70
 	shm_str_dup_macro(x->realm,realm);
71 71
 	if (!x->realm.s) goto error;	
72
+	shm_str_dup_macro(x->src_addr,src_addr);
73
+	if (!x->src_addr.s) goto error;
72 74
 	x->port = port;
73 75
 	x->lock = lock_alloc();
74 76
 	x->lock = lock_init(x->lock);
... ...
@@ -99,6 +101,7 @@ void free_peer(peer *x,int locked)
99 99
 	if (!locked) lock_get(x->lock);
100 100
 	if (x->fqdn.s) shm_free(x->fqdn.s);
101 101
 	if (x->realm.s) shm_free(x->realm.s);	
102
+	if (x->src_addr.s) shm_free(x->src_addr.s);
102 103
 	lock_destroy(x->lock);
103 104
 	lock_dealloc((void*)x->lock);
104 105
 	shm_free(x);
... ...
@@ -3,23 +3,23 @@
3 3
  *
4 4
  * Copyright (C) 2012 Smile Communications, jason.penton@smilecoms.com
5 5
  * Copyright (C) 2012 Smile Communications, richard.good@smilecoms.com
6
- * 
6
+ *
7 7
  * The initial version of this code was written by Dragos Vingarzan
8 8
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
9 9
  * Fruanhofer Institute. It was and still is maintained in a separate
10 10
  * branch of the original SER. We are therefore migrating it to
11 11
  * Kamailio/SR and look forward to maintaining it from here on out.
12 12
  * 2011/2012 Smile Communications, Pty. Ltd.
13
- * ported/maintained/improved by 
13
+ * ported/maintained/improved by
14 14
  * Jason Penton (jason(dot)penton(at)smilecoms.com and
15
- * Richard Good (richard(dot)good(at)smilecoms.com) as part of an 
15
+ * Richard Good (richard(dot)good(at)smilecoms.com) as part of an
16 16
  * effort to add full IMS support to Kamailio/SR using a new and
17 17
  * improved architecture
18
- * 
18
+ *
19 19
  * NB: Alot of this code was originally part of OpenIMSCore,
20
- * FhG Fokus. 
20
+ * FhG Fokus.
21 21
  * Copyright (C) 2004-2006 FhG Fokus
22
- * Thanks for great work! This is an effort to 
22
+ * Thanks for great work! This is an effort to
23 23
  * break apart the various CSCF functions into logically separate
24 24
  * components. We hope this will drive wider use. We also feel
25 25
  * that in this way the architecture is more complete and thereby easier
... ...
@@ -37,10 +37,10 @@
37 37
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38 38
  * GNU General Public License for more details.
39 39
  *
40
- * You should have received a copy of the GNU General Public License 
41
- * along with this program; if not, write to the Free Software 
40
+ * You should have received a copy of the GNU General Public License
41
+ * along with this program; if not, write to the Free Software
42 42
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
43
- * 
43
+ *
44 44
  */
45 45
 
46 46
 #ifndef __PEER_H
... ...
@@ -100,7 +100,8 @@ typedef struct _peer_t{
100 100
 	str fqdn;				/**< FQDN of the peer */
101 101
 	str realm;				/**< Realm of the peer */
102 102
 	int port;				/**< TCP Port of the peer */
103
-	
103
+	str src_addr;			/**< IP Address used to connect to the peer */
104
+
104 105
 	app_config *applications;/**< list of supported applications */
105 106
 	int applications_cnt;	/**< size of list of supporter applications*/
106 107
 	
... ...
@@ -127,7 +128,7 @@ typedef struct _peer_t{
127 127
 	struct _peer_t *prev;	/**< previous peer in the peer list */
128 128
 } peer;
129 129
 
130
-peer* new_peer(str fqdn,str realm,int port);
130
+peer* new_peer(str fqdn,str realm,int port,str src_addr);
131 131
 void free_peer(peer *x,int locked);
132 132
 
133 133
 inline void touch_peer(peer *p);
... ...
@@ -92,7 +92,7 @@ int peer_manager_init(dp_config *config)
92 92
 	*endtoend_id |= rand() & 0xFFFFF;
93 93
 
94 94
 	for(i=0;i<config->peers_cnt;i++){
95
-		p = new_peer(config->peers[i].fqdn,config->peers[i].realm,config->peers[i].port);
95
+		p = new_peer(config->peers[i].fqdn,config->peers[i].realm,config->peers[i].port,config->peers[i].src_addr);
96 96
 		if (!p) continue;
97 97
 		p->is_dynamic = 0;
98 98
 		add_peer(p);
... ...
@@ -209,6 +209,8 @@ peer *get_peer_from_sock(int sock)
209 209
 peer *get_peer_from_fqdn(str fqdn,str realm)
210 210
 {
211 211
 	peer *i;
212
+	str dumb;
213
+
212 214
 	lock_get(peer_list_lock);
213 215
 	i = peer_list->head;
214 216
 	while(i){
... ...
@@ -218,7 +220,7 @@ peer *get_peer_from_fqdn(str fqdn,str realm)
218 218
 	}
219 219
 	lock_release(peer_list_lock);
220 220
 	if (!i&&config->accept_unknown_peers){
221
-		i = new_peer(fqdn,realm,3868);
221
+		i = new_peer(fqdn,realm,3868,dumb);
222 222
 		if (i){
223 223
 			i->is_dynamic=1;
224 224
 			touch_peer(i);
... ...
@@ -836,7 +836,7 @@ int peer_connect(peer *p)
836 836
 	int sock;
837 837
 	unsigned int option = 1;
838 838
 
839
-	struct addrinfo *ainfo=0,*res=0,hints;
839
+	struct addrinfo *ainfo=0,*res=0,*sainfo=0,hints;
840 840
 	char buf[256],host[256],serv[256];
841 841
 	int error;
842 842
 
... ...
@@ -870,6 +870,25 @@ int peer_connect(peer *p)
870 870
 			continue;
871 871
 		}
872 872
 
873
+		/* try to set the local socket used to connect to the peer */
874
+		if (p->src_addr.s && p->src_addr.len > 0) {
875
+			LM_DBG("peer_connect(): connetting to peer via src addr=%.*s",p->src_addr.len, p->src_addr.s);
876
+			memset (&hints, 0, sizeof(hints));
877
+			hints.ai_flags = AI_NUMERICHOST;
878
+			hints.ai_socktype = SOCK_STREAM;
879
+			error = getaddrinfo(p->src_addr.s, NULL, &hints, &sainfo);
880
+
881
+			if (error!=0){
882
+				LM_WARN("peer_connect(): error getting client socket on %.*s:%s\n",
883
+					p->src_addr.len,p->src_addr.s,gai_strerror(error));
884
+			} else {
885
+				if (bind(sock, sainfo->ai_addr, sainfo->ai_addrlen )) {
886
+					LM_WARN("peer_connect(): error opening client socket on %.*s:%s\n",
887
+						p->src_addr.len,p->src_addr.s,strerror(errno));
888
+				}
889
+			}
890
+		}
891
+
873 892
 		{// Connect with timeout
874 893
 			int x;
875 894
 			x=fcntl(sock,F_GETFL,0);