Browse Source

Merge pull request #45 from grumvalski/cdp_src_addr

modules/cdp: added src_addr parameter in peer definition
Daniel-Constantin Mierla 10 years ago
parent
commit
b86ff789b8

+ 1 - 0
modules/cdp/config.h

@@ -54,6 +54,7 @@ typedef struct{
 	str fqdn;	/**< FQDN of the peer */
 	str realm;	/**< Realm of the peer */
 	int port;	/**< TCP port of the peer; the Diameter uri is then aaa://fqdn:port. */
+    str src_addr; /**< IP address used to connect to the peer */
 } peer_config;
 
 

+ 1 - 1
modules/cdp/configexample/ConfigExample.xml

@@ -54,7 +54,7 @@
 		a dedicated receiver process will be forked. All other unkwnown peers will share a single
 		receiver.
 	-->
-	<Peer FQDN="hss.open-ims.test" Realm="open-ims.test" port="3868"/>
+	<Peer FQDN="hss.open-ims.test" Realm="open-ims.test" port="3868" src_addr="192.168.1.1"/>
 
 	<!--
 		Definition of incoming connection acceptors. If no bind is specified, the acceptor will bind

+ 7 - 2
modules/cdp/configparser.c

@@ -331,7 +331,12 @@ dp_config* parse_dp_config(xmlDocPtr doc)
 				x->peers[x->peers_cnt].port = atoi((char*)xc);
 				xmlFree(xc);
 			}
-			x->peers_cnt++;		
+			xc = xmlGetProp(child,(xmlChar*)"src_addr");
+			if (xc){
+				quote_trim_dup(&(x->peers[x->peers_cnt].src_addr),(char*)xc);
+				xmlFree(xc);
+			}
+			x->peers_cnt++;
 		}
 		else if (xmlStrlen(child->name)==8 && strncasecmp((char*)child->name,"Acceptor",8)==0){
 			//Acceptor
@@ -459,7 +464,7 @@ dp_config* parse_dp_config(xmlDocPtr doc)
 												rei->next = re;
 												break;
 											}
-										} 					
+										}					
 								}
 							}
 						}

+ 4 - 1
modules/cdp/peer.c

@@ -56,7 +56,7 @@
  * @param port - port of the peer to connect to
  * @returns the new peer* if ok, NULL on error
  */
-peer* new_peer(str fqdn,str realm,int port)
+peer* new_peer(str fqdn,str realm,int port,str src_addr)
 {
 	peer *x;
 	x = shm_malloc(sizeof(peer));
@@ -69,6 +69,8 @@ peer* new_peer(str fqdn,str realm,int port)
 	if (!x->fqdn.s) goto error;	
 	shm_str_dup_macro(x->realm,realm);
 	if (!x->realm.s) goto error;	
+	shm_str_dup_macro(x->src_addr,src_addr);
+	if (!x->src_addr.s) goto error;
 	x->port = port;
 	x->lock = lock_alloc();
 	x->lock = lock_init(x->lock);
@@ -99,6 +101,7 @@ void free_peer(peer *x,int locked)
 	if (!locked) lock_get(x->lock);
 	if (x->fqdn.s) shm_free(x->fqdn.s);
 	if (x->realm.s) shm_free(x->realm.s);	
+	if (x->src_addr.s) shm_free(x->src_addr.s);
 	lock_destroy(x->lock);
 	lock_dealloc((void*)x->lock);
 	shm_free(x);

+ 12 - 11
modules/cdp/peer.h

@@ -3,23 +3,23 @@
  *
  * Copyright (C) 2012 Smile Communications, [email protected]
  * Copyright (C) 2012 Smile Communications, [email protected]
- * 
+ *
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * branch of the original SER. We are therefore migrating it to
  * Kamailio/SR and look forward to maintaining it from here on out.
  * 2011/2012 Smile Communications, Pty. Ltd.
- * ported/maintained/improved by 
+ * ported/maintained/improved by
  * Jason Penton (jason(dot)penton(at)smilecoms.com and
- * Richard Good (richard(dot)good(at)smilecoms.com) as part of an 
+ * Richard Good (richard(dot)good(at)smilecoms.com) as part of an
  * effort to add full IMS support to Kamailio/SR using a new and
  * improved architecture
- * 
+ *
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Fokus. 
+ * FhG Fokus.
  * Copyright (C) 2004-2006 FhG Fokus
- * Thanks for great work! This is an effort to 
+ * Thanks for great work! This is an effort to
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
@@ -37,10 +37,10 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  */
 
 #ifndef __PEER_H
@@ -100,7 +100,8 @@ typedef struct _peer_t{
 	str fqdn;				/**< FQDN of the peer */
 	str realm;				/**< Realm of the peer */
 	int port;				/**< TCP Port of the peer */
-	
+	str src_addr;			/**< IP Address used to connect to the peer */
+
 	app_config *applications;/**< list of supported applications */
 	int applications_cnt;	/**< size of list of supporter applications*/
 	
@@ -127,7 +128,7 @@ typedef struct _peer_t{
 	struct _peer_t *prev;	/**< previous peer in the peer list */
 } peer;
 
-peer* new_peer(str fqdn,str realm,int port);
+peer* new_peer(str fqdn,str realm,int port,str src_addr);
 void free_peer(peer *x,int locked);
 
 inline void touch_peer(peer *p);

+ 4 - 2
modules/cdp/peermanager.c

@@ -92,7 +92,7 @@ int peer_manager_init(dp_config *config)
 	*endtoend_id |= rand() & 0xFFFFF;
 
 	for(i=0;i<config->peers_cnt;i++){
-		p = new_peer(config->peers[i].fqdn,config->peers[i].realm,config->peers[i].port);
+		p = new_peer(config->peers[i].fqdn,config->peers[i].realm,config->peers[i].port,config->peers[i].src_addr);
 		if (!p) continue;
 		p->is_dynamic = 0;
 		add_peer(p);
@@ -209,6 +209,8 @@ peer *get_peer_from_sock(int sock)
 peer *get_peer_from_fqdn(str fqdn,str realm)
 {
 	peer *i;
+	str dumb;
+
 	lock_get(peer_list_lock);
 	i = peer_list->head;
 	while(i){
@@ -218,7 +220,7 @@ peer *get_peer_from_fqdn(str fqdn,str realm)
 	}
 	lock_release(peer_list_lock);
 	if (!i&&config->accept_unknown_peers){
-		i = new_peer(fqdn,realm,3868);
+		i = new_peer(fqdn,realm,3868,dumb);
 		if (i){
 			i->is_dynamic=1;
 			touch_peer(i);

+ 20 - 1
modules/cdp/receiver.c

@@ -836,7 +836,7 @@ int peer_connect(peer *p)
 	int sock;
 	unsigned int option = 1;
 
-	struct addrinfo *ainfo=0,*res=0,hints;
+	struct addrinfo *ainfo=0,*res=0,*sainfo=0,hints;
 	char buf[256],host[256],serv[256];
 	int error;
 
@@ -870,6 +870,25 @@ int peer_connect(peer *p)
 			continue;
 		}
 
+		/* try to set the local socket used to connect to the peer */
+		if (p->src_addr.s && p->src_addr.len > 0) {
+			LM_DBG("peer_connect(): connetting to peer via src addr=%.*s",p->src_addr.len, p->src_addr.s);
+			memset (&hints, 0, sizeof(hints));
+			hints.ai_flags = AI_NUMERICHOST;
+			hints.ai_socktype = SOCK_STREAM;
+			error = getaddrinfo(p->src_addr.s, NULL, &hints, &sainfo);
+
+			if (error!=0){
+				LM_WARN("peer_connect(): error getting client socket on %.*s:%s\n",
+					p->src_addr.len,p->src_addr.s,gai_strerror(error));
+			} else {
+				if (bind(sock, sainfo->ai_addr, sainfo->ai_addrlen )) {
+					LM_WARN("peer_connect(): error opening client socket on %.*s:%s\n",
+						p->src_addr.len,p->src_addr.s,strerror(errno));
+				}
+			}
+		}
+
 		{// Connect with timeout
 			int x;
 			x=fcntl(sock,F_GETFL,0);