libsua/sualibrary/sua/sua_datassoc.cpp

1097 lines
35 KiB
C++

/***************************************************************************
sua_datassoc.cpp - description
-------------------
begin : Tue Jan 8 2002
copyright : (C) 2002 by Lode Coene
email : lode.coene@siemens.atea.be
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/*
* $Id: sua_datassoc.cpp,v 1.9 2003/09/09 08:43:44 p82609 Exp $
*
* SUA implementation according to SUA draft issue 6.
*
* Author(s): Lode Coene
*
*
* Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
*
* Realized in co-operation between Siemens Atea and
* Siemens AG, Munich, Germany.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Contact: gery.verwimp@siemens.atea.be
* lode.coene@siemens.atea.be
*
* The alternative comment
* inspiration : Vera
* "You ain't seen nothing yet"
* "said Garfield the Ripper while putting on his binbag"
*
* Purpose: This code-file defines the SUA database access functions for
* SUA Association Object:
* - initialise association object
* - shutdown association
* - Dynamic association
* SUA Association List:
* - initialise association list
* - read source address
* - read Destination address
* - read source port
* - read destination port
* - read stream number
* - register instance
* - associate instance(initiating)
* - Find a association
* - Find a local SUA instance
* - Passive association instantiation(terminating)
* - shutdown a association
* - route on IP pointcode address
* - route on Global Title/Hostname
* - route message to a association
* - Final destination?
* - increase instance
* - Dynamic association setup(initiating)
*/
#include "sctp.h"
#include "sua_debug.h"
#include "sua_database.h"
#include "sua_asp_mgnt.h"
#include "sua_logging.h"
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <string>
#include <netinet/in.h>
#include "unistd.h"
using namespace std;
struct ulp_data_str {
int maximumStreamID;
unsigned int chunkCount;
};
static ulp_data_str ULPData[db_MAX_MULTIHOME_ADDR];
/***********************************************************************/
/* functions of the object class SUA Association Object */
/***********************************************************************/
/***********************************************************************/
/* Sua_AssociationObject::initalize */
/***********************************************************************/
void db_Sua_AssociationObject::initialize(){
short i;
Source.nr_of_addrs = 0;
Dest.nr_of_addrs = 0;
netw = nc_empty;
nr_of_inbound_streams = 0;
nr_of_outbound_streams = 0;
asp.status = asp_down;
for (i=0; i < db_MAX_MULTIHOME_ADDR; i++) {
Source.addrs[i].sa.sa_family = AF_INET;
Dest.addrs[i].sa.sa_family = AF_INET;
}
Source.pc.ITU24.pc = 0;
Dest.pc.ITU24.pc = 0;
for (i=0; i < db_MAX_1ASP_IN_AS; i++)
asp.linked_to_AS[i] = 0;
}
/***********************************************************************/
/* Sua_RemoteObject::shutdown_instance */
/***********************************************************************/
short db_Sua_AssociationObject:: shutdown(){
int result;
result = sctp_shutdown( SCTP_assoc_id );
return(result);
};
/***********************************************************************/
/* Sua_AssociationL::Dynamic_Associate */
/***********************************************************************/
unsigned int Dynamic_Associate( sccp_addr_str& cld,
sccp_addr_str& clg
)
{
return(0);
}
/***********************************************************************/
/* functions of the object class SUA AssociationList */
/***********************************************************************/
/***********************************************************************/
/* Sua_AssociationList::initalize */
/***********************************************************************/
void db_Sua_AssociationList::initialize(){
short i;
num_of_instance = 0;
for (i=0; i < db_MAX_REMOTE_SUA; i++) {
instance[i].initialize();
}
}
/***********************************************************************/
/* Sua_AssociationList::read_Source_addr */
/***********************************************************************/
void db_Sua_AssociationList:: read_Source_addr(string address){
instance[num_of_instance].Source.read_addr_param(address);
}
/***********************************************************************/
/* Sua_AssociationList::read_Dest_addr */
/***********************************************************************/
void db_Sua_AssociationList:: read_Dest_pointcode(string address){
instance[num_of_instance].Dest.read_pointcode_param(address);
}
/***********************************************************************/
/* Sua_AssociationList::read_Source_pointcode */
/***********************************************************************/
void db_Sua_AssociationList:: read_Source_pointcode(string address){
instance[num_of_instance].Source.read_pointcode_param(address);
}
/***********************************************************************/
/* Sua_AssociationList::read_Dest_addr */
/***********************************************************************/
void db_Sua_AssociationList:: read_Dest_addr(string address){
instance[num_of_instance].Dest.read_addr_param(address);
}
/***********************************************************************/
/* Sua_AssociationList::read_Source_port */
/***********************************************************************/
void db_Sua_AssociationList:: read_Source_port(string port){
instance[num_of_instance].Source.read_port_num(port);
}
/***********************************************************************/
/* Sua_AssociationList::read_Dest_port */
/***********************************************************************/
void db_Sua_AssociationList:: read_Dest_port(string port){
instance[num_of_instance].Dest.read_port_num(port);
}
/***********************************************************************/
/* Sua_AssociationList::read_stream_number */
/***********************************************************************/
void db_Sua_AssociationList:: read_stream_number(string stream_num){
int i=0;
char *tokstr = new char[stream_num.length()+1];
int sua_stream_nr;
stream_num.copy(tokstr,stream_num.length());
tokstr[stream_num.length()] = '\0';
sua_stream_nr = atoi(tokstr);
for(i = 1; i <= num_of_instance ; i++) {
instance[i].nr_of_inbound_streams = sua_stream_nr;
instance[i].nr_of_outbound_streams = sua_stream_nr;
}
}
/***********************************************************************/
/* Sua_AssociationList::associate_instance */
/***********************************************************************/
short db_Sua_AssociationList::
associate_instance( db_Sua_LocalList& local_sua,
db_Sua_RemoteList& remote_sua
){
int i;
SCTP_InstanceParameters SCTP_assoc_parms;
SCTP_InstanceParameters *SCTP_assoc_status = &SCTP_assoc_parms;
short sua_portnumber = SUA_PORT;
int res=0;
// get default values of association
res = sctp_getAssocDefaults( instance[1].SCTP_instance_name,
SCTP_assoc_status
);
// fill in the TOS field needed for DIFFSERV
SCTP_assoc_status->ipTos = 'a';
// set the new value for all associations
res = sctp_setAssocDefaults( instance[1].SCTP_assoc_id,
SCTP_assoc_status
);
for(i=1; i <= num_of_instance; i++)
{
/* init association from this node */
if ((instance[i].init_assoc) && (instance[i].Dest.nr_of_addrs != 0)) {
#ifdef DEBUG
cout << "Associate remote SUA(& SCTP) instance nr " << i << " with local SUA(& SCTP) instance nr " << instance[i].local_sua_id <<" \n";
#endif
char logstring[100];
sprintf(logstring, "Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", i, instance[i].local_sua_id );
event_log("sua_database.c",logstring);
if (instance[i].Dest.addrs[0].sa.sa_family == AF_INET)
sua_portnumber = instance[i].Dest.addrs[0].sin.sin_port;
else if (instance[i].Dest.addrs[0].sa.sa_family == AF_INET6)
sua_portnumber = instance[i].Dest.addrs[0].sin6.sin6_port;
ULPData[0].maximumStreamID = -1;
instance[i].SCTP_instance_name = local_sua.instance[instance[i].local_sua_id].SCTP_instance_name ;
instance[i].SCTP_assoc_id =
sctp_associate( instance[i].SCTP_instance_name,
instance[i].nr_of_outbound_streams,
instance[i].Dest.address_string[0],
sua_portnumber,
NULL
);
/* no msg queued, mark assoc down(from sua management viewpoint)*/
instance[i].asp.status = asp_down;
#ifdef DEBUG
cout << "SCTP association result = " << instance[i].SCTP_assoc_id <<" \n";
#endif
remote_sua.instance[instance[i].remote_sua_id].ssn.ssn = local_sua.instance[instance[i].local_sua_id].ssn.ssn;
}
}
return(0);
};
/***********************************************************************/
/* Sua_AssociationList::Find_association */
/***********************************************************************/
unsigned int db_Sua_AssociationList::
Find_association( unsigned int sctp_assoc_id,
unsigned int &Local_sua_id,
unsigned int &Remote_sua_id
)
{
short i = 0;
unsigned int sua_assoc_id = 0;
bool result = FALSE;
Local_sua_id = 0;
Remote_sua_id = 0;
while ((i < db_MAX_REMOTE_SUA) && !(result))
{
result = (instance[i].SCTP_assoc_id == sctp_assoc_id);
if (result) {
Local_sua_id = instance[i].local_sua_id;
/*Remote_sua_id = instance[i].remote_sua_id;*/
sua_assoc_id = i;
}
i++;
}
return(sua_assoc_id);
};
/***********************************************************************/
/* Sua_AssociationList::passive_associate */
/***********************************************************************/
unsigned int db_Sua_AssociationList::
passive_associate( unsigned int sctp_assoc_id,
db_Sua_LocalList &local_sua,
db_Sua_RemoteList &remote_sua,
unsigned short nr_of_dest_addr,
unsigned short nr_of_input_streams,
unsigned short nr_of_output_streams
)
{
SCTP_AssociationStatus status;
int result;
short k, j;
short i = 1, assoc_instance_idx = 0;
bool assoc_found = FALSE;
bool found_addr;
result = sctp_getAssocStatus( sctp_assoc_id,
&status
);
#ifdef DEBUG
cout << "SCTP association " << sctp_assoc_id <<" result = " << result<< "\n";
#endif
#ifdef DEBUG
cout << "number of asoc = " << num_of_instance << "\n";
#endif
while ((i <= num_of_instance) && !(assoc_found)){
assoc_found = (instance[i].Dest.nr_of_addrs == status.numberOfAddresses);
if (assoc_found)
{
k = 0;
found_addr = false;
#ifdef DEBUG
cout << "same number of addresses\n";
#endif
while ((k < instance[i].Dest.nr_of_addrs) && (!found_addr))
{
j=0;
found_addr = true;
while (instance[i].Dest.address_string[k][j] != '\0'){
found_addr = found_addr && (instance[i].Dest.address_string[k][j] == status.primaryDestinationAddress[j]) ;
j++;
}
k++;
}
if (found_addr){
#ifdef DEBUG
cout << "found same ip address\n";
#endif
assoc_found = ( found_addr && (instance[i].Dest.addrs[0].sin.sin_port == status.destPort));
assoc_instance_idx = i;
}
else
assoc_found = false;
}
i++;
}
if (!(assoc_found))
{
/* unknown association added */
/* not allowed: drop it */
#ifdef DEBUG
cout << "not found ???\n";
#endif
assoc_instance_idx = 0;
result = sctp_abort(sctp_assoc_id);
}
else
{
/* known association: no problemo */
instance[assoc_instance_idx].SCTP_assoc_id = sctp_assoc_id;
instance[assoc_instance_idx].remote_sua_id = 0;
remote_sua.instance[remote_sua.num_of_instance].ssn.ssn = local_sua.instance[instance[assoc_instance_idx].local_sua_id].ssn.ssn;
/* no msg queued, mark assoc down(from sua management viewpoint)*/
instance[assoc_instance_idx].asp.status = asp_down;
#ifdef DEBUG
cout << "Associate remote SUA(& SCTP) instance nr " << sctp_assoc_id << " with local SUA(& SCTP) instance nr " << assoc_instance_idx << " \n";
#endif
char logstring[100];
sprintf(logstring, "Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", sctp_assoc_id, assoc_instance_idx );
event_log("sua_database.c",logstring);
}
return(assoc_instance_idx);
}
/***********************************************************************/
/* Sua_AssociationList::shutdown_instance */
/***********************************************************************/
short db_Sua_AssociationList:: shutdown(){
int i;
short result;
for(i=1; i <= num_of_instance; i++)
{
#ifdef DEBUG
cout << "shutdown remote SUA(& SCTP) instance nr " << i << " with local SUA(& SCTP) instance nr " << instance[i].local_sua_id <<" \n";
#endif
char logstring[100];
sprintf(logstring, "Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", i, instance[i].local_sua_id );
event_log("sua_database.c",logstring);
result = instance[i].shutdown();
}
return(0);
};
/***********************************************************************/
/* Sua_AssociationList::increase_instance */
/***********************************************************************/
void db_Sua_AssociationList:: increase_instance(){
num_of_instance++;
}
/***********************************************************************/
/* Sua_AssociationList::Activate_Association */
/***********************************************************************/
bool db_Sua_AssociationList::activate( unsigned int sua_assoc_id,
short mode
)
{
return(instance[sua_assoc_id].asp.activate(mode,
sua_assoc_id
));
}
/***********************************************************************/
/* Sua_AssociationList::DeActivate_Association */
/***********************************************************************/
void db_Sua_AssociationList::deactivate( unsigned int sua_assoc_id,
short mode
)
{
instance[sua_assoc_id].asp.deactivate(mode,
sua_assoc_id
);
}
/***********************************************************************/
/* Sua_AssociationList::Down_Association */
/***********************************************************************/
void db_Sua_AssociationList::down( unsigned int sua_assoc_id,
short mode
)
{
instance[sua_assoc_id].asp.down(mode,
sua_assoc_id
);
}
/***********************************************************************/
/* Sua_AssociationList::Up_Association */
/***********************************************************************/
void db_Sua_AssociationList::up( unsigned int sua_assoc_id,
short mode
)
{
instance[sua_assoc_id].asp.up(mode,
sua_assoc_id
);
}
/***********************************************************************/
/* Sua_DatabaseList */
/***********************************************************************/
/***********************************************************************/
/* Sua_DatabaseList::initalize */
/***********************************************************************/
void db_Sua_DatabaseList::
initialize( )
{
/* init all parts of the SUA database */
local_sua.initialize();
remote_sua.initialize();
AssocDB.initialize();
NameDB.initialize();
ApplicServ.initialize();
}
/***********************************************************************/
/* Sua_DatabaseList::Find_local_sua */
/***********************************************************************/
unsigned int db_Sua_DatabaseList::
Find_local_sua( sccp_addr_str& local_address
)
{
pointcode_str dest_pc;
short i = 1, j = 0, k, count, addr_start, addr_stop;
unsigned int Local_sua_id = 0;
bool result = FALSE;
while ((i < db_MAX_LOCAL_SUA) && !(result))
{
j = 0;
while ((j < local_sua.instance[i].Source.nr_of_addrs) && !(result))
{
/* check IP address */
if (local_address.address_fields_present.pc == ipvx_pc_present)
{
result = (local_address.pc.ipvx.sa.sa_family == local_sua.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] == local_sua.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] == local_sua.instance[i].Source.addrs[j].ch[count]);
}
}
/* check SS7 pointcode */
else if (local_address.address_fields_present.pc == ss7_pc_present)
{
result = (local_address.pc.ss7.ITU14.family == local_sua.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 == local_sua.instance[i].Source.pc.ITU14.pc);
}
else
{
result = false;
cout << "ERROR Find_local_sua: Unknown SS7 pointcode addresstype\n";
}
}
/* check hostname */
else if (local_address.address_fields_present.name_gt == hostname_present)
{
count = 0;
result = NameDB.resolve_host_name ( local_address.name.HostName,
dest_pc
);
result = (dest_pc.ipvx.sa.sa_family == local_sua.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] == local_sua.instance[i].Source.addrs[j].ch[count]);
k++;
}
}
/* check global title */
else if (local_address.address_fields_present.name_gt == GT_present)
{
cout << "Find_local_sua: Global Title\n";
result =
(local_address.name.GT.nr_of_digits == local_sua.instance[i].Name.GT.nr_of_digits) &&
( local_address.name.GT.Translation_Type == local_sua.instance[i].Name.GT.Translation_Type) &&
( local_address.name.GT.Numbering_Plan == local_sua.instance[i].Name.GT.Numbering_Plan) &&
( local_address.name.GT.Nature_of_Address == local_sua.instance[i].Name.GT.Nature_of_Address) ;
for (k = 0; k < local_address.name.GT.nr_of_digits; k++)
{
result = result &&
( local_address.name.GT.digits[k] == local_sua.instance[i].Name.GT.digits[k]);
}
cout << "i = " << i << " Find_local_sua = " << result << "\n";
}
else
{
cout << "ERROR Find_local_sua: Unknown SUA addresstype\n";
result = false;
}
if (result)
{
Local_sua_id = i;
#ifdef DEBUG
cout << "Find_local_sua: local_sua_id = " << Local_sua_id << "\n";
#endif
}
j++;
}
i++;
}
return(Local_sua_id);
};
/***********************************************************************/
/* Sua_DatabaseList::route_on_IPpc */
/***********************************************************************/
signed int db_Sua_DatabaseList::
route_on_IPpc ( ipvxunion& dest_pc,
ipvxunion& org_pc,
int& sua_assoc_id
)
{
int j=0,i=1,count, addr_start, addr_stop;
unsigned int sctp_assoc_id = 0;
sua_assoc_id = 0;
bool cont = (i <= remote_sua.num_of_instance);
bool found_assoc = false;
while (cont)
{
found_assoc = false;
j = 0;
while ((j < remote_sua.instance[i].Dest.nr_of_addrs) && (!found_assoc))
{
found_assoc = (dest_pc.sa.sa_family == remote_sua.instance[i].Dest.addrs[j].sa.sa_family);
if (dest_pc.sa.sa_family == AF_INET)
{
addr_start = 4;
addr_stop = addr_start + 4;
}
else if (dest_pc.sa.sa_family == AF_INET6)
{
addr_start = 8;
addr_stop = addr_start + 16;
}
else
{
addr_start = 0;
addr_stop = 0;
found_assoc = false;
cout << "ERROR route_on_IPpc: Unknown addresstype\n";
}
/* compare the address family field */
found_assoc = found_assoc && (dest_pc.ch[1] == remote_sua.instance[i].Dest.addrs[j].ch[1]);
/* compare the ipv4/ipv6 address field */
for (count = addr_start; count < addr_stop; count++)
{
found_assoc = found_assoc
&& (dest_pc.ch[count] == remote_sua.instance[i].Dest.addrs[j].ch[count]);
}
j++;
}
if (found_assoc)
{
cont = false;
sua_assoc_id = remote_sua.instance[i].SUA_assoc_id;
sctp_assoc_id = AssocDB.instance[remote_sua.instance[i].SUA_assoc_id].SCTP_assoc_id;
#ifdef DEBUG
cout << "Remote sua " << i << " Sua association " << sua_assoc_id << " with SCTP assoc " << sctp_assoc_id << "\n";
if (dest_pc.sa.sa_family == AF_INET)
{
cout << "CLD ip v4 = " << dest_pc.sin.sin_addr.s_addr << "\n";
cout << "Remote IP = " << remote_sua.instance[i].Dest.addrs[0].sin.sin_addr.s_addr << "\n";
}
else if (dest_pc.sa.sa_family == AF_INET6)
{
cout << "CLD ip v6 = " << dest_pc.sin6.sin6_addr.s6_addr << "\n";
cout << "Remote IP = " << remote_sua.instance[i].Dest.addrs[0].sin6.sin6_addr.s6_addr << "\n";
}
else
cout << "Unknown CLD IP address type format\n";
#endif
}
else
{
i++;
cont = (i <= remote_sua.num_of_instance);
}
}
return(sctp_assoc_id);
}
/***********************************************************************/
/* Sua_DatabaseList::route_on_SS7pc */
/***********************************************************************/
signed int db_Sua_DatabaseList::
route_on_SS7pc ( SS7union& dest_pc,
SS7union& org_pc,
int& sua_assoc_id
)
{
int i=1;
unsigned int sctp_assoc_id = 0;
#ifdef DEBUG
cout << "route on SS7 PC\n";
cout << "PC family = " << dest_pc.ITU24.family << "\n";
cout << "PC value = " << dest_pc.ITU24.pc << "\n";
#endif
sua_assoc_id = 0;
bool cont = (i <= remote_sua.num_of_instance);
bool found_assoc = false;
while (cont)
{
if (dest_pc.ITU14.family == ITU14bit) // standard ITU: 14 bits
found_assoc = ((dest_pc.ITU14.pc == remote_sua.instance[i].Dest.pc.ITU14.pc));
else if (dest_pc.ITU24.family == ITU24bit) // chinese PC length: 24 bits
found_assoc = ((dest_pc.ITU24.pc == remote_sua.instance[i].Dest.pc.ITU24.pc));
else if (dest_pc.ANSI24.family == ANSI24bit) // ANSI PC length: 24 bits
found_assoc = ((dest_pc.ANSI24.pc == remote_sua.instance[i].Dest.pc.ANSI24.pc));
else
found_assoc = false;
if (found_assoc)
{
cont = false;
sua_assoc_id = remote_sua.instance[i].SUA_assoc_id;
sctp_assoc_id = AssocDB.instance[remote_sua.instance[i].SUA_assoc_id].SCTP_assoc_id;
#ifdef DEBUG
cout << "Remote sua " << i << " Sua association " << sua_assoc_id << " with SCTP assoc " << sctp_assoc_id << "\n";
cout << "CLD SS7 PC = " << dest_pc.ITU24.pc << "\n";
cout << "Remote PC = " << remote_sua.instance[i].Dest.pc.ITU24.pc << "\n";
#endif
}
else
{
i++;
cont = (i <= remote_sua.num_of_instance);
}
}
return(sctp_assoc_id);
}
/***********************************************************************/
/* Sua_DatabaseList::route_on_GTname */
/***********************************************************************/
signed int db_Sua_DatabaseList::
route_on_GTname ( hostname_str& dest_name,
hostname_str& org_name,
int& sua_assoc_id,
pointcode_str& dest_pc,
pointcode_str& org_pc
)
{
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) */
result = NameDB.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
);
if (sctp_assoc_id != 0 )
return(sctp_assoc_id);
return(sctp_assoc_id);
};
/***********************************************************************/
/* Sua_DatabaseList::route_on_GTT */
/***********************************************************************/
signed int db_Sua_DatabaseList::
route_on_GTT ( global_title_str& dest_gt,
global_title_str& org_gt,
int& sua_assoc_id,
pointcode_str& dest_pc,
pointcode_str& org_pc
)
{
int result = 0;
unsigned int sctp_assoc_id = 0;
global_title_str dest_tr_gt, org_tr_gt;
sua_assoc_id = 0;
/* resolving can be done via: */
/* - local global Titel database */
result = NameDB.perform_GTT ( dest_gt,
org_gt,
dest_tr_gt,
org_tr_gt,
dest_pc
);
#ifdef DEBUG
cout << "result of GT translation : " << result << "\n";
cout << "dest IP address = " << dest_pc.ipvx.sa.sa_family << "\n";
#endif
sctp_assoc_id = route_on_IPpc( dest_pc.ipvx,
org_pc.ipvx,
sua_assoc_id
);
if (sctp_assoc_id != 0 )
return(sctp_assoc_id);
return(sctp_assoc_id);
};
/***********************************************************************/
/* Sua_DatabaseList::route_msg */
/***********************************************************************/
signed int db_Sua_DatabaseList::
route_msg( sccp_addr_str& cld,
sccp_addr_str& clg,
int& sua_assoc_id
){
unsigned int sctp_assoc_id = 0;
sua_assoc_id = 0;
#ifdef DEBUG
cout << "number of associations instances= : "<< AssocDB.num_of_instance << "\n";
cout << "number of remote sua instances= : "<< remote_sua.num_of_instance << "\n";
#endif
if ((cld.address_fields_present.pc == ipvx_pc_present) &&
(cld.routing_ind == route_on_ssn))
{
sctp_assoc_id = route_on_IPpc( cld.pc.ipvx,
clg.pc.ipvx,
sua_assoc_id
);
}
else if ((cld.address_fields_present.name_gt == hostname_present) &&
(cld.routing_ind == route_on_name_gt))
{
sctp_assoc_id = route_on_GTname( cld.name.HostName,
clg.name.HostName,
sua_assoc_id,
cld.pc,
clg.pc
);
}
else if ((cld.address_fields_present.name_gt == GT_present) &&
(cld.routing_ind == route_on_name_gt))
{
sctp_assoc_id = route_on_GTT( cld.name.GT,
clg.name.GT,
sua_assoc_id,
cld.pc,
clg.pc
);
}
else if ((cld.address_fields_present.name_gt == hostname_present) &&
(cld.address_fields_present.pc == ipvx_pc_present) &&
(cld.routing_ind == route_on_name_gt_next_office))
{
sctp_assoc_id = route_on_IPpc( cld.pc.ipvx,
clg.pc.ipvx,
sua_assoc_id
);
}
else if ((cld.address_fields_present.pc == ss7_pc_present) &&
(cld.routing_ind == route_on_ssn))
{
sctp_assoc_id = route_on_SS7pc( cld.pc.ss7,
clg.pc.ss7,
sua_assoc_id
);
}
else
{
cout << "Unknown routing requested\n";
}
#ifdef SUA_MANAGEMENT
/* check if allowed to send msg over the association */
if ((sua_assoc_id > 0) &&
(sua_assoc_id <= AssocDB.num_of_instance) &&
(AssocDB.instance[sua_assoc_id].asp.status != asp_active))
{
sctp_assoc_id = (-sctp_assoc_id);
}
#endif
#ifdef DEBUG
cout << "route msg towards remote SUA(& SCTP) association " << sctp_assoc_id << " \n";
#endif
char logstring[100];
sprintf(logstring, "Route msg towards Remote SUA(& SCTP) instance nr %d", sctp_assoc_id );
event_log("sua_database.c",logstring);
return(sctp_assoc_id);
};
/***********************************************************************/
/* Sua_DatabaseList::Dynamic_Associate */
/***********************************************************************/
unsigned int db_Sua_DatabaseList::Dynamic_Associate( sccp_addr_str& cld,
sccp_addr_str& clg,
unsigned short nr_of_dest_addr,
unsigned short nr_of_input_streams,
unsigned short nr_of_output_streams
)
{
short sua_portnumber = SUA_PORT;
short i = 1, assoc_instance_idx = 1, assoc_source_idx = 0;
bool partial_assoc_found = FALSE;
while ((i <= AssocDB.num_of_instance) && !(partial_assoc_found)){
partial_assoc_found = (AssocDB.instance[i].Dest.nr_of_addrs == 0);
if (partial_assoc_found)
assoc_instance_idx = i;
i++;
}
if (!(partial_assoc_found))
{
/* all assoc's are complete, allocate a new one */
AssocDB.num_of_instance++;
assoc_instance_idx = AssocDB.num_of_instance;
}
assoc_source_idx = Find_local_sua ( clg);
#ifdef DEBUG
cout << " assoc source idx = " << assoc_source_idx << ", assoc_instance_idx = " << assoc_instance_idx << "\n";
#endif
AssocDB.instance[assoc_instance_idx].Source = AssocDB.instance[assoc_source_idx].Source;
AssocDB.instance[assoc_instance_idx].SCTP_instance_name = AssocDB.instance[assoc_source_idx].SCTP_instance_name;
AssocDB.instance[assoc_instance_idx].local_sua_id = AssocDB.instance[assoc_source_idx].local_sua_id;
AssocDB.instance[assoc_instance_idx].nr_of_inbound_streams = nr_of_input_streams ;
AssocDB.instance[assoc_instance_idx].nr_of_outbound_streams = nr_of_input_streams ;
/* conversion and fill in the destination address */
AssocDB.instance[assoc_instance_idx].Dest.nr_of_addrs = 1;
AssocDB.instance[assoc_instance_idx].Dest.addrs[0] = cld.pc.ipvx;
short k;
const char *ptr;
for(k=0; k < AssocDB.instance[assoc_instance_idx].Dest.nr_of_addrs ; k++)
{
if ( AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET )
ptr = inet_ntop( AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family,
&AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sin.sin_addr,
(char *)AssocDB.instance[assoc_instance_idx].Dest.address_string[k],
SCTP_MAX_IP_LEN
);
else if ( AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET6 )
ptr = inet_ntop( AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family,
&AssocDB.instance[assoc_instance_idx].Dest.addrs[k].sin6.sin6_addr,
(char *)AssocDB.instance[assoc_instance_idx].Dest.address_string[k],
SCTP_MAX_IP_LEN
);
else
cout << "Unsupported address family in dynamic associate\n";
}
remote_sua.increase_instance();
AssocDB.instance[assoc_instance_idx].SCTP_assoc_id =
sctp_associate( AssocDB.instance[assoc_instance_idx].SCTP_instance_name,
AssocDB.instance[assoc_instance_idx].nr_of_outbound_streams,
AssocDB.instance[assoc_instance_idx].Dest.address_string[0],
sua_portnumber,
NULL
);
AssocDB.instance[assoc_instance_idx].remote_sua_id = remote_sua.num_of_instance;
remote_sua.instance[remote_sua.num_of_instance].ssn.ssn = local_sua.instance[AssocDB.instance[assoc_instance_idx].local_sua_id].ssn.ssn;
/* a message is queued for this association -> send decision is taken */
/* on receiving the communicationUp notification of SCTP AND whether */
/* SUA management is going to be used */
AssocDB.instance[assoc_instance_idx].asp.status = asp_down_traf_hold;
#ifdef DEBUG
cout << "Dynamic Associate remote SUA(& SCTP) instance nr " << assoc_instance_idx << " with local SUA(& SCTP) instance nr " << AssocDB.instance[assoc_instance_idx].local_sua_id << " \n";
#endif
char logstring[100];
sprintf(logstring, "Dynamic Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", assoc_instance_idx, AssocDB.instance[assoc_instance_idx].local_sua_id );
event_log("sua_datasoc.c",logstring);
return(assoc_instance_idx);
}
// end of module sua_database.c