aboutsummaryrefslogtreecommitdiffstats
path: root/sualibrary/sua/sua_datassoc.cpp
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-07-09 20:56:56 +0200
committerHarald Welte <laforge@gnumonks.org>2010-07-09 20:56:56 +0200
commit7e7186ca00b33e9735c809ce200e310636006a22 (patch)
tree37ae4c48db5cfb2218830a7237a69ec787613f0b /sualibrary/sua/sua_datassoc.cpp
parentacd8cf60130f88a4dd477dde5506faa4c142540c (diff)
update to sualibrary-0.1.1 from 2002-03-15:
* Contains Relaying functionality using hostnames. * Correct some bugs (multihoming....) * Compiles and runs on Linux, FreeBSD .... * Tested on IPv4 and IPV6 networks * interoperable with other SUA implementations * corresponds to sua draft v11 * requires SCTP implementation from www.sctp.de
Diffstat (limited to 'sualibrary/sua/sua_datassoc.cpp')
-rw-r--r--sualibrary/sua/sua_datassoc.cpp288
1 files changed, 210 insertions, 78 deletions
diff --git a/sualibrary/sua/sua_datassoc.cpp b/sualibrary/sua/sua_datassoc.cpp
index c3bcc5f..dd29625 100644
--- a/sualibrary/sua/sua_datassoc.cpp
+++ b/sualibrary/sua/sua_datassoc.cpp
@@ -15,7 +15,7 @@
* *
***************************************************************************/
/*
- * $Id: sua_datassoc.cpp,v 1.3 2002/02/15 16:19:46 p82609 Exp $
+ * $Id: sua_datassoc.cpp,v 1.6 2002/03/15 12:53:53 p82609 Exp $
*
* SUA implementation according to SUA draft issue 6.
*
@@ -70,6 +70,7 @@
* - route on IP pointcode address
* - route on Global Title/Hostname
* - route message to a association
+ * - Final destination?
* - increase instance
* - Dynamic association setup(initiating)
*/
@@ -240,6 +241,66 @@ void db_Sua_AssociationList:: read_stream_number(string stream_num){
}
/***********************************************************************/
+/* db_Sua_AssociationList::resolve_host_name */
+/***********************************************************************/
+signed int db_Sua_AssociationList::resolve_host_name ( hostname_str& dest_name,
+ pointcode_str& dest_pc
+ )
+{
+ struct hostent *hptr;
+ char **pptr;
+ char str[INET6_ADDRSTRLEN];
+ char *dest_carr;
+
+ /* resolving can be done via: */
+ /* - local global Titel database */
+ /* - resolve hostname via DNS(simplest for single hop translations) */
+ dest_carr = dest_name;
+
+ if ((hptr = gethostbyname( dest_carr )) == NULL)
+ {
+ cout << "Hostname " << dest_name << " not known in DNS.\n";
+ return(-1);
+ }
+
+#ifdef DEBUG
+ cout << "Hostname " << dest_name << " resolved to dest IP address(es)\n";
+ cout << "IP address length = "<< hptr->h_length << "\n";
+#endif
+
+ /* initialise the length field of the structure: */
+ /* length field is NOT always present in every Unix like operating system */
+ dest_pc.ipvx.ch[0] = 0;
+
+ pptr = hptr->h_addr_list;
+ for ( ; (*pptr != NULL) ;pptr++)
+ {
+ inet_ntop(hptr->h_addrtype, *pptr, str,sizeof(str));
+#ifdef DEBUG
+ cout << str << "\n";
+#endif
+ /* got a IP address */
+ dest_pc.ipvx.sa.sa_family = hptr->h_addrtype;
+ if (dest_pc.ipvx.sa.sa_family == AF_INET)
+ inet_pton( AF_INET,
+ str,
+ &dest_pc.ipvx.sin.sin_addr
+ );
+ else if (dest_pc.ipvx.sa.sa_family == AF_INET6)
+ inet_pton( AF_INET6,
+ str,
+ &dest_pc.ipvx.sin6.sin6_addr
+ );
+ else
+ {
+ cout << "ERROR resolve_host_name: Unknown IP addresstype\n";
+ return(-2);
+ }
+ }
+ return(0);
+};
+
+/***********************************************************************/
/* Sua_AssociationList::register_instance */
/***********************************************************************/
short db_Sua_AssociationList::
@@ -390,28 +451,125 @@ Find_association( unsigned int sctp_assoc_id,
/***********************************************************************/
unsigned int db_Sua_AssociationList::
Find_local_sua( sccp_addr_str& local_address
- )
+ )
{
- short i = 1, j = 0;
- unsigned int Local_sua_id = 0;
- bool result = FALSE;
+ pointcode_str dest_pc;
+ short i = 1, j = 0, count, addr_start, addr_stop;
+ unsigned int Local_sua_id = 0;
+ bool result = FALSE;
while ((i < db_MAX_REMOTE_SUA) && !(result) && (instance[i].Source.nr_of_addrs != 0))
{
j = 0;
while ((j < instance[i].Source.nr_of_addrs) && !(result))
- {
- result = ((instance[i].Source.addrs[j].sin.sin_addr.s_addr == local_address.pc.ipvx.sin.sin_addr.s_addr) ||
+ {
+ /*result = ((instance[i].Source.addrs[j].sin.sin_addr.s_addr == local_address.pc.ipvx.sin.sin_addr.s_addr) ||
(instance[i].Source.addrs[j].sin6.sin6_addr.s6_addr == local_address.pc.ipvx.sin6.sin6_addr.s6_addr));
- if (result)
- {
- Local_sua_id = instance[i].local_sua_id;
+*/
+ if (local_address.address_fields_present.pc == ipvx_pc_present)
+ {
+ result = (local_address.pc.ipvx.sa.sa_family == instance[i].Source.addrs[j].sa.sa_family);
+ if (local_address.pc.ipvx.sa.sa_family == AF_INET)
+ {
+ addr_start = 4;
+ addr_stop = addr_start + 4;
+ }
+ else if (local_address.pc.ipvx.sa.sa_family == AF_INET6)
+ {
+ addr_start = 8;
+ addr_stop = addr_start + 16;
+ }
+ else
+ {
+ addr_start = 0;
+ addr_stop = 0;
+ result = false;
+ cout << "ERROR Find_local_sua: Unknown IPvx addresstype\n";
+ }
+ /* compare the address family field */
+ result = result &&
+ (local_address.pc.ipvx.ch[1] == instance[i].Source.addrs[j].ch[1]);
+
+ /* compare the ipv4/ipv6 address field */
+ for (count = addr_start; count < addr_stop; count++)
+ {
+ result = result &&
+ (local_address.pc.ipvx.ch[count] == instance[i].Source.addrs[j].ch[count]);
+ }
+ }
+ else if (local_address.address_fields_present.pc == ss7_pc_present)
+ {
+ result = (local_address.pc.ss7.ITU14.family == instance[i].Source.pc.ITU14.family);
+ if (((local_address.pc.ss7.ITU14.family == ITU14bit) ||
+ (local_address.pc.ss7.ITU14.family == ITU24bit)) ||
+ (local_address.pc.ss7.ITU14.family == ANSI24bit))
+ {
+ /* compare the ITU 14/24bit or ANSI 24bit PC address field */
+ result = result &&
+ (local_address.pc.ss7.ITU14.pc == instance[i].Source.pc.ITU14.pc);
+ }
+ else
+ {
+ result = false;
+ cout << "ERROR Find_local_sua: Unknown SS7 pointcode addresstype\n";
+ }
+ }
+ else if (local_address.address_fields_present.name_gt == hostname_present)
+ {
+ count = 0;
+ result = resolve_host_name ( local_address.name.HostName,
+ dest_pc
+ );
+
+ result = (dest_pc.ipvx.sa.sa_family == instance[i].Source.addrs[j].sa.sa_family);
+
+ if (dest_pc.ipvx.sa.sa_family == AF_INET)
+ {
+ addr_start = 4;
+ addr_stop = addr_start + 4;
+ }
+ else if (dest_pc.ipvx.sa.sa_family == AF_INET6)
+ {
+ addr_start = 8;
+ addr_stop = addr_start + 16;
+ }
+ else
+ {
+ addr_start = 0;
+ addr_stop = 0;
+ result = false;
+ cout << "ERROR Find_local_sua: Unknown IPvx addresstype\n";
+ }
+ /* compare the address family field : already done */
+ /* compare the ipv4/ipv6 address field */
+ short k=0;
+ for (count = addr_start; count < addr_stop; count++)
+ {
+ result = result &&
+ (dest_pc.ipvx.ch[count] == instance[i].Source.addrs[j].ch[count]);
+ k++;
+ }
+
+ }
+ else if (local_address.address_fields_present.name_gt == GT_present)
+ {
+ cout << "ERROR Find_local_sua: GT code not implemented yet\n";
+ }
+ else
+ {
+ cout << "ERROR Find_local_sua: Unknown SUA addresstype\n";
+ result = false;
+ }
+
+ if (result)
+ {
+ Local_sua_id = instance[i].local_sua_id;
#ifdef DEBUG
- cout << "local_sua_id = " << Local_sua_id << " , instance "<< i << "\n";
+ cout << "Find_local_sua: local_sua_id = " << Local_sua_id << " , instance "<< i << "\n";
#endif
- }
- j++;
- }
+ }
+ j++;
+ }
i++;
}
@@ -431,6 +589,7 @@ passive_associate( unsigned int assoc_id,
){
SCTP_AssociationStatus status;
+ SCTP_Path_Status path_x_status;
int result;
short k;
int bla;
@@ -471,13 +630,21 @@ passive_associate( unsigned int assoc_id,
event_log("sua_database.c",logstring);
- result = sctp_getAssocStatus(instance[assoc_instance_idx].SCTP_assoc_id, &status);
+ result = sctp_getAssocStatus( instance[assoc_instance_idx].SCTP_assoc_id,
+ &status
+ );
/* conversion and fill in the destination address */
instance[assoc_instance_idx].Dest.nr_of_addrs = nr_of_dest_addr;
- instance[assoc_instance_idx].Dest.address_string[0] = status.primaryDestinationAddress;
- instance[assoc_instance_idx].Dest.addrs[0].sin.sin_port = status.destPort;
-
+ for(k=0; k < instance[assoc_instance_idx].Dest.nr_of_addrs ; k++)
+ {
+ result = sctp_getPathStatus( instance[assoc_instance_idx].SCTP_assoc_id,
+ k,
+ &path_x_status
+ );
+ instance[assoc_instance_idx].Dest.address_string[k] = path_x_status.destinationAddress;
+ instance[assoc_instance_idx].Dest.addrs[k].sin.sin_port = status.destPort;
+ }
/* try to figure out ipv4 or v6 address family: get it from the source address */
k = 0;
instance[assoc_instance_idx].Dest.addrs[0].sa.sa_family = AF_LOCAL;
@@ -692,72 +859,36 @@ route_on_SS7pc ( SS7union& dest_pc,
/***********************************************************************/
signed int db_Sua_AssociationList::
route_on_GTname ( hostname_str& dest_name,
- hostname_str& org_name,
- int& sua_assoc_id,
- pointcode_str& dest_pc,
- pointcode_str& org_pc
- )
+ hostname_str& org_name,
+ int& sua_assoc_id,
+ pointcode_str& dest_pc,
+ pointcode_str& org_pc
+ )
{
- struct hostent *hptr;
- char **pptr;
- unsigned int sctp_assoc_id = 0;
- char str[INET6_ADDRSTRLEN];
- char *dest_carr;
+ int result = 0;
+ unsigned int sctp_assoc_id = 0;
sua_assoc_id = 0;
/* resolving can be done via: */
/* - local global Titel database */
/* - resolve hostname via DNS(simplest for single hop translations) */
- dest_carr = dest_name;
-
- if ((hptr = gethostbyname( dest_carr )) == NULL)
- {
- cout << "Hostname " << dest_name << " not known in DNS.\n";
- return(-1);
- }
-
-#ifdef DEBUG
- cout << "Hostname " << dest_name << " resolved to dest IP address(es)\n";
- cout << "IP address length = "<< hptr->h_length << "\n";
-#endif
-
- /* initialise the length field of the structure: */
- /* length field is NOT always present in every Unix like operating system */
- dest_pc.ipvx.ch[0] = 0;
- org_pc.ipvx.ch[0] = 0;
-
- pptr = hptr->h_addr_list;
- for ( ; (*pptr != NULL) ;pptr++)
- {
- inet_ntop(hptr->h_addrtype, *pptr, str,sizeof(str));
-#ifdef DEBUG
- cout << str << "\n";
-#endif
- /* got IP address, look if association already exists */
- dest_pc.ipvx.sa.sa_family = hptr->h_addrtype;
- if (dest_pc.ipvx.sa.sa_family == AF_INET)
- inet_pton( AF_INET,
- str,
- &dest_pc.ipvx.sin.sin_addr
- );
- else if (dest_pc.ipvx.sa.sa_family == AF_INET6)
- inet_pton( AF_INET6,
- str,
- &dest_pc.ipvx.sin6.sin6_addr
- );
- else
- cout << "ERROR route_on_GTname: Unknown IP addresstype\n";
+ result = resolve_host_name ( dest_name,
+ dest_pc
+ );
+
+ /*result = resolve_host_name ( org_name,
+ org_pc
+ ); */
- sctp_assoc_id = route_on_IPpc( dest_pc.ipvx,
- org_pc.ipvx,
- sua_assoc_id
- );
+ sctp_assoc_id = route_on_IPpc( dest_pc.ipvx,
+ org_pc.ipvx,
+ sua_assoc_id
+ );
- if (sctp_assoc_id != 0 )
- return(sctp_assoc_id);
+ if (sctp_assoc_id != 0 )
+ return(sctp_assoc_id);
- }
return(sctp_assoc_id);
};
@@ -766,12 +897,14 @@ route_on_GTname ( hostname_str& dest_name,
/* Sua_AssociationList::route_msg */
/***********************************************************************/
signed int db_Sua_AssociationList::
-route_msg( sccp_addr_str& cld,
- sccp_addr_str& clg
+route_msg( sccp_addr_str& cld,
+ sccp_addr_str& clg,
+ int& sua_assoc_id
){
unsigned int sctp_assoc_id = 0;
- int sua_assoc_id = 0;
+
+ sua_assoc_id = 0;
#ifdef DEBUG
cout << "num_of_instance : "<< num_of_instance << "\n";
@@ -837,7 +970,6 @@ route_msg( sccp_addr_str& cld,
return(sctp_assoc_id);
};
-
/***********************************************************************/
/* Sua_AssociationList::increase_instance */
/***********************************************************************/