/****************************************************************************** * Copyright (c) 2000-2019 Ericsson Telecom AB * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html * * Contributors: * Zoltan Bibo - initial implementation and initial documentation * Akos Cserveni * Attila Balasko * Csaba Bela Koppany * Csaba Feher * Eduard Czimbalmos * Endre Szalai * Gabor Szalai * Janos Kovesdi * Jozsef Gyurusi * Tibor Csondes * Zoltan Jasz ******************************************************************************/ // // File: TCPasp_PT.cc // Description: TCP test port source // Rev: R9A // Prodnr: CNL 113 347 // #include #include #include #include #include "TCPasp_PT.hh" #include "TCPasp_PortType.hh" namespace TCPasp__PortType { TCPasp__PT_PROVIDER::TCPasp__PT_PROVIDER(const char *par_port_name) : PORT(par_port_name), #ifdef AS_USE_SSL SSL_Socket("TCP", par_port_name) #else Abstract_Socket("TCP", par_port_name) #endif { header_descr = NULL; is_packet_hdr_length_offset = FALSE; is_packet_hdr_nr_bytes_in_length = FALSE; is_packet_hdr_byte_order = FALSE; is_packet_hdr_length_value_offset = FALSE; is_packet_hdr_length_multiplier = FALSE; packet_hdr_length_offset = 0; packet_hdr_nr_bytes_in_length = 0; packet_hdr_length_value_offset = 0; packet_hdr_length_multiplier = 1; packet_hdr_byte_order = PacketHeaderDescr::Header_MSB; } TCPasp__PT_PROVIDER::~TCPasp__PT_PROVIDER() { delete header_descr; } void TCPasp__PT_PROVIDER::set_parameter(const char *parameter_name, const char *parameter_value) { log_debug("entering TCPasp__PT_PROVIDER::set_parameter(%s, %s)", parameter_name, parameter_value); if(strcmp(parameter_name, "packet_hdr_length_offset") == 0) { is_packet_hdr_length_offset = TRUE; long int_value; if (sscanf(parameter_value, "%ld", &int_value) != 1 || int_value < 0) log_error("The value of parameter 'packet_hdr_length_offset' " "must be a non-negative integer"); packet_hdr_length_offset = int_value; } else if(strcmp(parameter_name, "packet_hdr_nr_bytes_in_length") == 0) { is_packet_hdr_nr_bytes_in_length = TRUE; long int_value; if(sscanf(parameter_value, "%ld", &int_value) != 1 || int_value < 0) log_error("The value of parameter 'packet_hdr_nr_bytes_in_length' " "must be a non-negative integer"); packet_hdr_nr_bytes_in_length = int_value; } else if(strcmp(parameter_name, "packet_hdr_byte_order") == 0) { is_packet_hdr_byte_order = TRUE; if(strcmp(parameter_value, "MSB") == 0) { packet_hdr_byte_order = PacketHeaderDescr::Header_MSB; } else if (strcmp(parameter_value, "LSB") == 0){ packet_hdr_byte_order = PacketHeaderDescr::Header_LSB;} else log_error("Parameter value '%s' not recognized for parameter " "'packet_hdr_byte_order' Possible values: \"MSB\" or \"LSB\"", parameter_value); } else if(strcmp(parameter_name, "packet_hdr_length_value_offset") == 0) { is_packet_hdr_length_value_offset = TRUE; long int_value; if(sscanf(parameter_value, "%ld", &int_value) != 1) log_error("The value of parameter 'packet_hdr_length_value_offset' " "must be a number"); packet_hdr_length_value_offset = int_value; } else if(strcmp(parameter_name, "packet_hdr_length_multiplier") == 0) { is_packet_hdr_length_multiplier = TRUE; long int_value; if(sscanf(parameter_value, "%ld", &int_value) != 1 || int_value <= 0) log_error("The value of parameter 'packet_hdr_length_multiplier' " "must be a positive integer"); packet_hdr_length_multiplier = int_value; } else { if(!parameter_set(parameter_name ,parameter_value)) TTCN_warning("TCPasp__PT_PROVIDER::set_parameter(): Unsupported Test Port parameter: %s", parameter_name); } log_debug("leaving TCPasp__PT_PROVIDER::set_parameter(%s, %s)", parameter_name, parameter_value); } void TCPasp__PT_PROVIDER::Handle_Fd_Event(int fd, boolean is_readable, boolean is_writable, boolean is_error) { log_debug("entering TCPasp__PT_PROVIDER::Handle_Fd_Event()"); Handle_Socket_Event(fd, is_readable, is_writable, is_error); log_debug("leaving TCPasp__PT_PROVIDER::Handle_Fd_Event()"); } void TCPasp__PT_PROVIDER::Handle_Timeout(double time_since_last_call) { log_debug("entering TCPasp__PT_PROVIDER::Handle_Timeout()"); Handle_Timeout_Event(time_since_last_call); log_debug("leaving TCPasp__PT_PROVIDER::Handle_Timeout()"); } void TCPasp__PT_PROVIDER::message_incoming(const unsigned char* msg, int messageLength, int client_id) { log_debug("entering TCPasp__PT_PROVIDER::message_incoming()"); TCPasp__Types::ASP__TCP parameters; parameters.data() = OCTETSTRING(messageLength, msg); if(client_id != -1) { parameters.client__id() = client_id; } else { parameters.client__id() = OMIT_VALUE; } incoming_message(parameters); log_debug("leaving TCPasp__PT_PROVIDER::message_incoming()"); } void TCPasp__PT_PROVIDER::peer_disconnected(int client_id) { log_debug("entering TCPasp__PT_PROVIDER::peer_disconnected()"); if(get_use_connection_ASPs()) { TCPasp__Types::ASP__TCP__Close asp; asp.client__id() = client_id; incoming_message(asp); } else Abstract_Socket::peer_disconnected(client_id); log_debug("leaving TCPasp__PT_PROVIDER::peer_disconnected()"); } void TCPasp__PT_PROVIDER::user_map(const char */*system_port*/) { log_debug("entering TCPasp__PT_PROVIDER::user_map()"); if (is_packet_hdr_nr_bytes_in_length) { header_descr = new PacketHeaderDescr(packet_hdr_length_offset, packet_hdr_nr_bytes_in_length, packet_hdr_byte_order, packet_hdr_length_value_offset, packet_hdr_length_multiplier); } else { if (is_packet_hdr_length_offset) log_error("Parameter 'packet_hdr_length_offset' cannot be used without " "'packet_hdr_nr_bytes_in_length'"); if (is_packet_hdr_byte_order) log_error("Parameter 'packet_hdr_byte_order' cannot be used without " "'packet_hdr_nr_bytes_in_length'"); if (is_packet_hdr_length_value_offset) log_error("Parameter 'packet_hdr_length_value_offset' cannot be used " "without 'packet_hdr_nr_bytes_in_length'"); if (is_packet_hdr_length_multiplier) log_error("Parameter 'packet_hdr_length_multiplier' cannot be used " "without 'packet_hdr_nr_bytes_in_length'"); } if(!get_use_connection_ASPs()) map_user(); log_debug("leaving TCPasp__PT_PROVIDER::user_map()"); } void TCPasp__PT_PROVIDER::user_unmap(const char */*system_port*/) { log_debug("entering TCPasp__PT_PROVIDER::user_unmap()"); unmap_user(); delete header_descr; header_descr = NULL; log_debug("leaving TCPasp__PT_PROVIDER::user_unmap()"); } void TCPasp__PT_PROVIDER::user_start() { log_debug("entering TCPasp__PT_PROVIDER::user_start()"); log_debug("leaving TCPasp__PT_PROVIDER::user_start()"); } void TCPasp__PT_PROVIDER::user_stop() { log_debug("entering TCPasp__PT_PROVIDER::user_stop()"); log_debug("leaving TCPasp__PT_PROVIDER::user_stop()"); } void TCPasp__PT_PROVIDER::outgoing_send(const TCPasp__Types::ASP__TCP& send_par) { log_debug("entering TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP)"); if(send_par.client__id().is_bound() && send_par.client__id().ispresent()) { send_outgoing((const unsigned char*)send_par.data(), send_par.data().lengthof(), send_par.client__id()()); } else { send_outgoing((const unsigned char*)send_par.data(), send_par.data().lengthof()); } log_debug("leaving TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP)"); } void TCPasp__PT_PROVIDER::outgoing_send(const TCPasp__Types::ASP__TCP__Connect& send_par) { log_debug("entering TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP__Connect)"); char remotePort[6]; char localPort[6]; const char* localHostname = NULL; char* localServicename = NULL; sprintf(remotePort, "%d", (int)send_par.portnumber()); if(send_par.local__hostname().is_bound() && send_par.local__hostname().ispresent()) { localHostname = send_par.local__hostname()(); } else { localHostname = get_local_host_name(); if (localHostname) log_debug("using local host name configured in %s: %s", local_address_name(), localHostname); else log_debug("using 'localhost' as local host name"); } if(send_par.local__portnumber().is_bound() && send_par.local__portnumber().ispresent()) { sprintf(localPort, "%d", (int)send_par.local__portnumber()()); localServicename = localPort; } else if (get_local_port_number()>0) { log_debug("using local port number configured in %s: %d", local_port_name(), get_local_port_number()); sprintf(localPort, "%d", get_local_port_number()); localServicename = localPort; } else { log_debug("using ephemeral local port number"); } open_client_connection(send_par.hostname(), remotePort, localHostname, localServicename); log_debug("leaving TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP__Connect)"); } void TCPasp__PT_PROVIDER::report_error(int client_id, int msg_length, int sent_length, const unsigned char* msg, const char* error_text) { log_debug("entering TCPasp__PT_PROVIDER::report_error"); if(get_use_connection_ASPs()){ TCPasp__Types::ASP__TCP__Send__error asp; if(client_id!=-1) asp.client__id() = client_id; else asp.client__id() = OMIT_VALUE; asp.data()=OCTETSTRING(msg_length,msg); asp.os__error__code()=errno; if(sent_length==-2){ asp.sent__octets()=0; asp.error__type()=0; //TCP__SEND__INVALID__CLIENT__ID; } else if(sent_length==-1) { asp.sent__octets()=0; asp.error__type()=1; //TCP__SEND__ERROR; } else { asp.sent__octets()=sent_length; asp.error__type()=2; //TCP__SEND__MESSAGE__NOT__COMPLETE; } char *emsg=strerror(errno); if(emsg) asp.os__error__text()=emsg; else asp.os__error__text()=""; asp.ttcn__error__text()=error_text; incoming_message(asp); errno=0; } else log_error("%s",error_text); log_debug("leaving TCPasp__PT_PROVIDER::report_error"); } const PacketHeaderDescr *TCPasp__PT_PROVIDER::Get_Header_Descriptor() const { return header_descr; } void TCPasp__PT_PROVIDER::client_connection_opened(int client_id) { log_debug("entering TCPasp__PT_PROVIDER::client_connection_opened(%d)", client_id); if(get_use_connection_ASPs()) { TCPasp__Types::ASP__TCP__Connect__result asp; asp.client__id() = client_id; incoming_message(asp); } else Abstract_Socket::client_connection_opened(client_id); log_debug("leaving TCPasp__PT_PROVIDER::client_connection_opened()"); } void TCPasp__PT_PROVIDER::peer_connected(int client_id, const char * host, const int port) { log_debug("entering TCPasp__PT_PROVIDER::peer_connected(%d, %s, %d)", client_id, host, port); if(get_use_connection_ASPs()) { TCPasp__Types::ASP__TCP__Connected asp; asp.hostname() = host; asp.portnumber() = port; asp.client__id() = client_id; incoming_message(asp); } log_debug("leaving TCPasp__PT_PROVIDER::peer_connected()"); } void TCPasp__PT_PROVIDER::outgoing_send(const TCPasp__Types::ASP__TCP__Close& send_par) { log_debug("entering TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP__Close)"); if(send_par.client__id().is_bound() && send_par.client__id().ispresent()) remove_client((int)send_par.client__id()()); else remove_all_clients(); log_debug("leaving TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP__Close)"); } void TCPasp__PT_PROVIDER::outgoing_send(const TCPasp__Types::ASP__TCP__Listen& send_par) { log_debug("entering TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP__Listen)"); char localPort[7]; const char* localServicename = NULL; const char* localHostname = NULL; if(send_par.local__hostname().is_bound() && send_par.local__hostname().ispresent()) { localHostname = send_par.local__hostname()(); } else { localHostname = get_local_host_name(); if (localHostname) { log_debug("using local host name configured in %s: %s", local_address_name(), get_local_host_name()); } else { log_debug("using 'localhost' as local host name"); } } if(send_par.portnumber().is_bound() && send_par.portnumber().ispresent()) { sprintf(localPort, "%d", (int)send_par.portnumber()()); localServicename = (const char*)&localPort; } else if (get_local_port_number()>0) { log_debug("using local port number configured in %s: %d", local_port_name(), get_local_port_number()); sprintf(localPort, "%d", get_local_port_number()); localServicename = localPort; } else { log_debug("using ephemeral local port number"); } open_listen_port(localHostname, localServicename); log_debug("leaving TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP__Listen)"); } void TCPasp__PT_PROVIDER::listen_port_opened(int port_number) { log_debug("entering TCPasp__PT_PROVIDER::listen_port_opened(%d)", port_number); if(get_use_connection_ASPs()) { TCPasp__Types::ASP__TCP__Listen__result asp; asp.portnumber() = port_number; incoming_message(asp); } else Abstract_Socket::listen_port_opened(port_number); log_debug("leaving TCPasp__PT_PROVIDER::listen_port_opened()"); } void TCPasp__PT_PROVIDER::outgoing_send(const TCPasp__Types::ASP__TCP__Shutdown& /*send_par*/) { log_debug("entering TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP__Shutdown)"); close_listen_port(); log_debug("leaving TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP__Shutdown)"); } void TCPasp__PT_PROVIDER::outgoing_send(const TCPasp__Types::ASP__TCP__SetAddressFamily& send_par) { log_debug("entering TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP__SetAddressFamily)"); if (send_par == TCPasp__Types::c__TCP__AF__INET || send_par == TCPasp__Types::c__TCP__IPv4) { set_ai_family(AF_INET); log_debug("Address family set to %s", (const char*)send_par); } else if (send_par == TCPasp__Types::c__TCP__AF__INET6 || send_par == TCPasp__Types::c__TCP__IPv6) { set_ai_family(AF_INET6); log_debug("Address family set to %s", (const char*)send_par); } else if(send_par == TCPasp__Types::c__TCP__AF__UNSPEC || send_par == TCPasp__Types::c__TCP__UNSPEC) { set_ai_family(AF_UNSPEC); log_debug("Address family set to %s", (const char*)send_par); } else { log_warning("Address family %s is not allowed. Ignored.", (const char*)send_par); } log_debug("leaving TCPasp__PT_PROVIDER::outgoing_send(ASP__TCP__SetAddressFamily)"); } const char* TCPasp__PT_PROVIDER::local_port_name() { return "serverPort";} const char* TCPasp__PT_PROVIDER::remote_address_name() { return "destIPAddr";} const char* TCPasp__PT_PROVIDER::local_address_name() { return "serverIPAddr";} const char* TCPasp__PT_PROVIDER::remote_port_name() { return "destPort";} const char* TCPasp__PT_PROVIDER::ai_family_name() { return "addressFamily";} const char* TCPasp__PT_PROVIDER::halt_on_connection_reset_name(){ return "halt_on_connection_reset";} const char* TCPasp__PT_PROVIDER::server_mode_name() { return "server_mode";} const char* TCPasp__PT_PROVIDER::socket_debugging_name() { return "socket_debugging";} const char* TCPasp__PT_PROVIDER::nagling_name() { return "nagling";} const char* TCPasp__PT_PROVIDER::server_backlog_name() { return "server_backlog";} const char* TCPasp__PT_PROVIDER::ssl_use_ssl_name() { return "ssl_use_ssl";} const char* TCPasp__PT_PROVIDER::ssl_use_session_resumption_name() { return "ssl_use_session_resumption";} const char* TCPasp__PT_PROVIDER::ssl_private_key_file_name() { return "ssl_private_key_file";} const char* TCPasp__PT_PROVIDER::ssl_trustedCAlist_file_name() { return "ssl_trustedCAlist_file";} const char* TCPasp__PT_PROVIDER::ssl_certificate_file_name() { return "ssl_certificate_chain_file";} const char* TCPasp__PT_PROVIDER::ssl_password_name() { return "ssl_private_key_password";} const char* TCPasp__PT_PROVIDER::ssl_cipher_list_name() { return "ssl_allowed_ciphers_list";} const char* TCPasp__PT_PROVIDER::ssl_verifycertificate_name() { return "ssl_verify_certificate";} }//namespace