/////////////////////////////////////////////////////////////////////////////// // // 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 /////////////////////////////////////////////////////////////////////////////// // // File: IPL4asp_PT.hh #ifndef IPL4asp__PT_HH #define IPL4asp__PT_HH #include #include // The IPv6 should be disabled if not needed for some crazy reason // But the code uses the macro to enable it. // So if it is not disabled define the enable macro #ifndef NO_IPV6 #define USE_IPV6 #endif // In order to symplify the sctp usage th euser should define only one // sctp handling macro // Which should be the USE_SCTP only, but for backward compatibility // it checks for the old ones #if defined LKSCTP_1_0_7 || defined LKSCTP_1_0_9 #ifndef USE_SCTP #define USE_SCTP #endif #endif // enable the SCTP if the SCTP multihoming is requested #ifdef LKSCTP_MULTIHOMING_ENABLED #ifndef USE_SCTP #define USE_SCTP #endif #endif #ifdef USE_SCTP #include // Magic to figure out the version of the lksctp lib // the SCTP_ADAPTION_LAYER defined only the very old versions < 1.0.7 // the SCTP_AUTH_CHUNK defined if version >= 1.0.9 #ifdef SCTP_ADAPTION_LAYER #ifdef LKSCTP_1_0_7 #undef LKSCTP_1_0_7 #error LKSCTP_1_0_7 defined but the lksctp older than 1.0.7. Use only -DUSE_SCTP, version is automatically selected #endif #ifdef LKSCTP_1_0_9 #error LKSCTP_1_0_9 defined but the lksctp older than 1.0.7. Use only -DUSE_SCTP, version is automatically selected #undef LKSCTP_1_0_9 #endif #else // 1.0.7 or newer #ifdef SCTP_AUTH_CHUNK // 1.0.9 or newer #ifdef LKSCTP_1_0_7 #undef LKSCTP_1_0_7 #error LKSCTP_1_0_7 defined but the lksctp newer than 1.0.7. Use only -DUSE_SCTP, version is automatically selected #endif #ifndef LKSCTP_1_0_9 #define LKSCTP_1_0_9 #endif #else // 1.0.7 #ifdef LKSCTP_1_0_9 #undef LKSCTP_1_0_9 #error LKSCTP_1_0_9 defined but the lksctp older than 1.0.9. Use only -DUSE_SCTP, version is automatically selected #endif #ifndef LKSCTP_1_0_7 #define LKSCTP_1_0_7 #endif #endif #endif #endif #ifdef USE_IPL4_EIN_SCTP #include "SS7Common.hh" #include "00sctpapi.h" // figure out the EINSS7 version // undef the EIN_R3B macro #ifdef EIN_R3B #undef EIN_R3B #endif // define it only if needed // that macro is defined in R3B, but not in th eolder ones. #ifdef EINSS7_00SCTP_INVALID_TAG_POINTER #define EIN_R3B #endif #endif #include #include #include "IPL4asp_Types.hh" #include "Socket_API_Definitions.hh" //SSL #ifdef IPL4_USE_SSL #include #include #include #include #include #define IPL4_COOKIE_SECRET_LENGTH 16 #endif namespace IPL4asp__PortType { struct thread_log{ TTCN_Logger::Severity severity; char *msg; }; typedef int sctp_assoc_t; #if (defined(SOLARIS) && !defined(_SOCKLEN_T)) || defined(WIN32) typedef int socklen_t; #endif #define RECV_MAX_LEN 65535 #define ADDR_LEN_MAX 64 #define N_RECENTLY_CLOSED 10 //Number of recently closed sockets not to assign #define SOCK_LIST_SIZE_MIN 16 enum SSL_STATES {STATE_DONT_RECEIVE, STATE_WAIT_FOR_RECEIVE_CALLBACK, STATE_BLOCK_FOR_SENDING, STATE_DONT_CLOSE, STATE_NORMAL, STATE_CONNECTING, STATE_HANDSHAKING}; struct SSL_Suport { int SSLv2; /* YES, NO, NOT_SET */ int SSLv3; /* YES, NO, NOT_SET */ int TLSv1; /* YES, NO, NOT_SET */ int TLSv1_1; /* YES, NO, NOT_SET */ int TLSv1_2; /* YES, NO, NOT_SET */ int DTLSv1; /* YES, NO, NOT_SET */ int DTLSv1_2; /* YES, NO, NOT_SET */ SSL_Suport(): SSLv2(-1), /* NOT_SET */ SSLv3(-1), /* NOT_SET */ TLSv1(-1), /* NOT_SET */ TLSv1_1(-1), /* NOT_SET */ TLSv1_2(-1), /* NOT_SET */ DTLSv1(-1), /* NOT_SET */ DTLSv1_2(-1) /* NOT_SET */ {} SSL_Suport(int s2,int s3,int t1, int t11, int t12, int dt1, int dt12): SSLv2(s2), SSLv3(s3), TLSv1(t1), TLSv1_1(t11), TLSv1_2(t12), DTLSv1(dt1), DTLSv1_2(dt12) {} }; enum SSL_HANDSHAKE_RESULT { SUCCESS, FAIL, WANT_READ, WANT_WRITE }; typedef enum { NONE, CLIENT, SERVER } SSL_TLS_Type; typedef enum { IPL4asp_UDP, //IPL4asp_UDP_LIGHT, IPL4asp_TCP_LISTEN, IPL4asp_TCP, IPL4asp_SCTP_LISTEN, IPL4asp_SCTP } SockType; typedef union { struct sockaddr_storage ss; struct sockaddr_in v4; #ifdef USE_IPV6 struct sockaddr_in6 v6; #endif } SockAddr; typedef struct { enum { SOCK_NONEX = -1, SOCK_CLOSED = -2, SOCK_NOT_KNOWN = -3, WAIT_FOR_RELEASE = -4 }; enum { ACTION_NONE = 0, ACTION_BIND = 1, ACTION_CONNECT = 2 , ACTION_DELETE = 3}; SockType type; SSL_TLS_Type ssl_tls_type; int sock; // -1: nonexistent, -2: closed TTCN_Buffer **buf; sctp_assoc_t *assocIdList; unsigned int cnt; int userData; Socket__API__Definitions::f__getMsgLen getMsgLen; Socket__API__Definitions::f__getMsgLen getMsgLen_forConnClosedEvent; Socket__API__Definitions::ro__integer *msgLenArgs; Socket__API__Definitions::ro__integer *msgLenArgs_forConnClosedEvent; int msgLen; // -1 or the message length returned by getMsgLen int nextFree; // -1 or index of next free element int parentIdx; // parent index (-1 if no) #ifdef IPL4_USE_SSL SSL* sslObj; BIO* bio; SSL_CTX* sslCTX; #endif char* dtlsSrtpProfiles; // DTLS SRTP profiles, see RCF 5764 char *ssl_key_file; // private key file char *ssl_certificate_file; // own certificate file char *ssl_trustedCAlist_file; // trusted CA list file char *ssl_cipher_list; // ssl_cipher list restriction to apply char *ssl_password; // password to decode the private key char *psk_identity; char *psk_identity_hint; char *psk_key; bool server; bool sctpHandshakeCompletedBeforeDtls; SockAddr sa_client; SSL_Suport ssl_supp; SSL_STATES sslState; Socket__API__Definitions::PortNumber *localport; CHARSTRING *localaddr; Socket__API__Definitions::PortNumber *remoteport; CHARSTRING *remoteaddr; CHARSTRING *tls_hostname; OCTETSTRING* alpn; #ifdef USE_IPL4_EIN_SCTP int next_action; int endpoint_id; int ref_count; int remote_addr_index; int maxOs; Socket__API__Definitions::SocketList remote_addr_list; #endif void clear(); } SockDesc; int SetSockAddr(const char *name, int port, SockAddr& sa, socklen_t& saLen); struct IPDiscConfig { enum Type { NONE = 0, DHCP, DHCP_OR_ARP, ARP }; Type type; CHARSTRING expIfName; CHARSTRING expIfIpAddress; CHARSTRING exclIfIpAddress; CHARSTRING ethernetAddress; unsigned int leaseTime; CHARSTRING leaseFile; unsigned int nOfAddresses; bool debugAllowed; unsigned int dhcpMsgRetransmitCount; unsigned int dhcpMsgRetransmitPeriodInms; unsigned int dhcpMaxParallelRequestCount; unsigned int dhcpTimeout; unsigned int arpMsgRetransmitCount; unsigned int arpMsgRetransmitPeriodInms; unsigned int arpMaxParallelRequestCount; IPDiscConfig () : type ( NONE ), leaseTime ( 0 ), nOfAddresses ( 0 ), debugAllowed ( false ), dhcpMsgRetransmitCount ( 5 ), dhcpMsgRetransmitPeriodInms ( 3000 ), dhcpMaxParallelRequestCount ( 25 ), dhcpTimeout ( 1000000000 ), arpMsgRetransmitCount ( 3 ), arpMsgRetransmitPeriodInms ( 1000 ), arpMaxParallelRequestCount ( 50 ) {} }; struct IPAddrLease { CHARSTRING ifName; CHARSTRING leaseFile; }; struct GlobalConnOpts { enum { NOT_SET = -1 }; enum { NO = 0, YES = 1 }; enum { METHOD_ZERO = 0, METHOD_ONE= 1, METHOD_TWO = 2 }; int connection_method; /* METHOD_ZERO, METHOD_ONE, METHOD_TWO*/ int tcpReuseAddr; /* YES, NO, NOT_SET */ int udpReuseAddr; /* YES, NO, NOT_SET */ int sctpReuseAddr; /* YES, NO, NOT_SET */ int sslReuseAddr; /* YES, NO, NOT_SET */ int tcpKeepAlive; /* YES, NO, NOT_SET */ int tcpKeepCnt; /* NOT_SET, 0.. */ int tcpKeepIdle; /* NOT_SET, 0.. */ int tcpKeepIntvl; /* NOT_SET, 0.. */ int sslKeepAlive; /* YES, NO, NOT_SET */ int sslKeepCnt; /* NOT_SET, 0.. */ int sslKeepIdle; /* NOT_SET, 0.. */ int sslKeepIntvl; /* NOT_SET, 0.. */ int extendedPortEvents;/* YES, NO, NOT_SET */ int sinit_num_ostreams; /* 64, 0.. */ //sctp specific params starts here int sinit_max_instreams; /* 64, 0.. */ int sinit_max_attempts; /* 0, 0.. */ int sinit_max_init_timeo; /* 0, 0.. */ int sctp_data_io_event; /* YES, NO, NOT_SET */ int sctp_association_event; /* YES, NO, NOT_SET */ int sctp_address_event; /* YES, NO, NOT_SET */ int sctp_send_failure_event; /* YES, NO, NOT_SET */ int sctp_peer_error_event; /* YES, NO, NOT_SET */ int sctp_shutdown_event; /* YES, NO, NOT_SET */ int sctp_partial_delivery_event; /* YES, NO, NOT_SET */ int sctp_adaptation_layer_event; /* YES, NO, NOT_SET */ int sctp_authentication_event; /* YES, NO, NOT_SET */; int sctp_sender_dry_event; int tcp_nodelay; /* YES, NO, NOT_SET */ int sctp_nodelay; /* YES, NO, NOT_SET */ int freebind; SSL_Suport ssl_supp; char* dtlsSrtpProfiles; /* SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80 */; int dscp; /* NOT_SET, 0.. */ GlobalConnOpts () : connection_method ( METHOD_ZERO ), tcpReuseAddr ( YES ), #ifdef LINUX udpReuseAddr ( YES ), sctpReuseAddr ( YES ), #else udpReuseAddr ( NO ), sctpReuseAddr ( NO ), #endif sslReuseAddr(YES), tcpKeepAlive ( NOT_SET ), tcpKeepCnt ( NOT_SET ), tcpKeepIdle ( NOT_SET ), tcpKeepIntvl ( NOT_SET ), sslKeepAlive ( NOT_SET ), sslKeepCnt ( NOT_SET ), sslKeepIdle ( NOT_SET ), sslKeepIntvl ( NOT_SET ), extendedPortEvents ( NO ), sinit_num_ostreams ( 64 ), sinit_max_instreams ( 64 ), sinit_max_attempts ( 0 ), sinit_max_init_timeo ( 0 ), sctp_data_io_event ( YES ), sctp_association_event ( YES ), sctp_address_event ( YES ), sctp_send_failure_event ( YES ), sctp_peer_error_event ( YES ), sctp_shutdown_event ( YES ), sctp_partial_delivery_event ( YES ), sctp_adaptation_layer_event ( YES ), sctp_authentication_event ( NO ), sctp_sender_dry_event ( NO ), tcp_nodelay (NOT_SET), //ssl_nodelay (NOT_SET), sctp_nodelay (NOT_SET), freebind(NOT_SET), ssl_supp(YES,YES,YES,YES,YES,YES,YES ), dtlsSrtpProfiles (NULL), dscp (NOT_SET) {} }; class IPL4asp__PT_PROVIDER : public PORT { public: IPL4asp__PT_PROVIDER(const char *par_port_name = NULL); ~IPL4asp__PT_PROVIDER(); void set_parameter(const char *parameter_name, const char *parameter_value); IPDiscConfig ipDiscConfig; IPAddrLease ipAddrLease; void debug(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); int outgoing_send_core(const IPL4asp__Types::ASP__Send& asp, Socket__API__Definitions::Result& result); int outgoing_send_core(const IPL4asp__Types::ASP__SendTo& asp, Socket__API__Definitions::Result& result); void starttls(const IPL4asp__Types::ConnectionId& connId, const BOOLEAN& server_side, Socket__API__Definitions::Result& result); void stoptls(const IPL4asp__Types::ConnectionId& connId, Socket__API__Definitions::Result& result); OCTETSTRING exportTlsKey(const IPL4asp__Types::ConnectionId& connId, const CHARSTRING& label, const OCTETSTRING& context, const INTEGER& keyLen); IPL4asp__Types::IPL4__SrtpKeysAndSalts exportSrtpKeysAndSalts(const IPL4asp__Types::ConnectionId& connId); OCTETSTRING exportSctpKey(const IPL4asp__Types::ConnectionId& connId); CHARSTRING getLocalCertificateFingerprint(const IPL4asp__Types::IPL4__DigestMethods& method,const IPL4asp__Types::ConnectionId& connId, const CHARSTRING& certificate__file); CHARSTRING getPeerCertificateFingerprint(const IPL4asp__Types::ConnectionId& connId, const IPL4asp__Types::IPL4__DigestMethods& method); CHARSTRING getSelectedSrtpProfile(const IPL4asp__Types::ConnectionId& connId); // bool setDtlsSrtpProfiles(const IPL4asp__Types::ConnectionId& connId,const IPL4asp__Types::OptionList& options); char *defaultLocHost; int defaultLocPort; char *defaultRemHost; int defaultRemPort; int default_mode; // 0 - normal, 1 - auto connect, 2 - auto listen int default_proto; // 0 - tcp, 1 - tls, 2 - sctp, 3 - udp bool connId_release_confirmed; protected: void user_map(const char *system_port); void user_unmap(const char *system_port); void user_start(); void user_stop(); void outgoing_send(const IPL4asp__Types::ASP__Send& asp); void outgoing_send(const IPL4asp__Types::ASP__SendTo& asp); virtual void incoming_message(const IPL4asp__Types::ASP__Event& incoming_par) = 0; virtual void incoming_message(const IPL4asp__Types::ASP__RecvFrom& incoming_par) = 0; virtual void incoming_message(const IPL4asp__Types::ASP__ConnId__ReadyToRelease& incoming_par) = 0; #ifdef IPL4_USE_SSL //increase buffer size bool increase_send_buffer(int fd, int &old_size, int& new_size); void set_psk(int connId); void set_usePskHint(int connId,SSL_CTX *selectedSslCtx); void set_psk_ex_data(int connId); char *get_pskIdentity(int connId); char *get_pskIdHint(int connId); char *get_pskKey(int connId); //SSL // creates SSL context and SSL_obj for TLS and DTLS // It will create a new SSL conenction on the top of the TCP connection. virtual bool ssl_create_contexts_and_obj(int client_id); // Called after a TCP connection is established (client side or server accepted a connection). // It will create a new SSL connection on the top of the TCP connection. virtual SSL_HANDSHAKE_RESULT perform_ssl_handshake(int client_id); // Called after a TCP connection is closed. // It will delete the SSL conenction. virtual bool perform_ssl_shutdown(int client_id); // Called from all_mandatory_configparameters_present() function // during map() operation to check mandatory parameter presents. virtual bool user_all_mandatory_configparameters_present(int clientId); // Called after an SSL connection is established (handshake finished) for further // authentication. Shall return 'true' if verification // is OK, otherwise 'false'. If return value was 'true', the connection is kept, otherwise // the connection will be shutted down. virtual bool ssl_verify_certificates(); // Call during SSL handshake (and rehandshake as well) by OpenSSL // Return values: // ==1: user authentication is passed, go on with handshake // ==0: user authentication failed, refuse the connection to the other peer // <0 : user don't care, go on with default basic checks // virtual int ssl_verify_certificates_at_handshake(int preverify_ok, X509_STORE_CTX *ssl_ctx); // Called to receive from the socket if data is available (select()). // Shall return with 0 if the peer is disconnected or with the number of bytes read. // If error occured, execution shall stop in the function by calling log_error() // The function passes the ssl error message as well. virtual int receive_ssl_message_on_fd(int client_id, int* error_msg); // Called to send message (SSL_write()). virtual void write_ssl_message_on_fd(int* ret, int* rem, const int connId, const unsigned char *msg_ptr); // Called to send a message on the socket. // Shall return with 0 if the peer is disconnected or with the number of bytes written. // If error occured, execution shall stop in the function by calling log_error() //virtual int send_message_on_fd(int client_id, const unsigned char * message_buffer, int length_of_message); //virtual int send_message_on_nonblocking_fd(int client_id, const unsigned char * message_buffer, int length_of_message); // The following members can be called to fetch the current values //bool get_ssl_use_ssl() const {return ssl_use_ssl;} // bool get_ssl_verifycertificate() const {return ssl_verify_certificate;} // bool get_ssl_use_session_resumption() const {return ssl_use_session_resumption;} // bool get_ssl_initialized() const {return ssl_initialized;} // char * get_ssl_key_file() const {return ssl_key_file;} // char * get_ssl_certificate_file() const {return ssl_certificate_file;} // char * get_ssl_trustedCAlist_file() const {return ssl_trustedCAlist_file;} // char * get_ssl_cipher_list() const {return ssl_cipher_list;} char * get_ssl_password() const; const unsigned char * get_ssl_server_auth_session_id_context() const {return ssl_server_auth_session_id_context;} // const SSL_METHOD * get_current_ssl_method() const {return ssl_method;} // const SSL_CIPHER * get_current_ssl_cipher() const {return ssl_cipher;} SSL_SESSION* get_current_ssl_session() const {return ssl_session;} SSL_CTX * get_current_ssl_ctx() const {return ssl_ctx;} SSL_CTX * get_current_ssl_dtls_server_ctx() const {return ssl_dtls_server_ctx;} SSL_CTX * get_current_ssl_dtls_client_ctx() const {return ssl_dtls_client_ctx;} SSL * get_current_ssl() const {return ssl_current_ssl;} SSL_CTX * get_selected_ssl_ctx(int) const; bool getSslObj(int connId, SSL*& sslObj); bool setSslObj(int connId, SSL* sslObj); // The following members can be called to set the current values // NOTE that in case the parameter_value is a char *pointer, the old character // array is deleted by these functions automatically. // void set_ssl_verifycertificate(bool parameter_value); // void set_ssl_use_session_resumption(bool parameter_value); // void set_ssl_key_file(char * parameter_value); // void set_ssl_certificate_file(char * parameter_value); // void set_ssl_trustedCAlist_file(char * parameter_value); // void set_ssl_cipher_list(char * parameter_value); // void set_ssl_server_auth_session_id_context(const unsigned char * parameter_value); // The following members can be called to fetch the default test port parameter names virtual const char* ssl_use_session_resumption_name(); virtual const char* ssl_private_key_file_name(); virtual const char* ssl_trustedCAlist_file_name(); virtual const char* ssl_certificate_file_name(); virtual const char* ssl_password_name(); //virtual const char* ssl_dtls_srtp_profiles_name(); virtual const char* ssl_cipher_list_name(); virtual const char* ssl_verifycertificate_name(); virtual const char* psk_identity_name(); virtual const char* psk_identity_hint_name(); virtual const char* psk_key_name(); #endif public: // Logging functions void log_debug(const char *fmt, ...) const __attribute__ ((__format__ (__printf__, 2, 3))); void log_warning(const char *fmt, ...) const __attribute__ ((__format__ (__printf__, 2, 3))); void log_hex(const char *prompt, const unsigned char *msg, size_t length) const; inline bool isConnIdValid(int connId) const { return ((unsigned int)connId < sockListSize && connId > 0 && sockList != 0 && sockList[connId].sock > 0); } inline bool isConnIdReleaseWait(int connId) const { return ((unsigned int)connId < sockListSize && connId > 0 && sockList != 0 && sockList[connId].sock == SockDesc::WAIT_FOR_RELEASE); } SockDesc *sockList; void ConnFree(int connId); private: void Handle_Fd_Event_Error(int fd); void Handle_Fd_Event_Writable(int fd); void Handle_Fd_Event_Readable(int fd); void handle_event(int fd, int connId, const void *buf); int getmsg(int fd, int connId, struct msghdr *msg,void *buf, size_t *buflen, ssize_t *nrp, size_t cmsglen); int getmsg(int fd, int connId, ssize_t *nrp, int *ssl_err_msg); int ConnAdd(SockType type, int sock, SSL_TLS_Type ssl_tls_type,const IPL4asp__Types::OptionList *options=NULL, int parentIdx = -1); int ConnDel(int connId,bool forced=false); int setUserData(int id, int userData); int getUserData(int id, int& userData); int getConnectionDetails(int id, IPL4asp__Types::IPL4__Param IPL4param, IPL4asp__Types::IPL4__ParamResult& IPL4paramResult); void sendError(Socket__API__Definitions::PortError code, const Socket__API__Definitions::ConnectionId& id, int os_error_code = 0); void reportRemainingData_beforeConnClosed(const Socket__API__Definitions::ConnectionId& id, const CHARSTRING& remoteaddr, const Socket__API__Definitions::PortNumber& remoteport, const CHARSTRING& localaddr, const Socket__API__Definitions::PortNumber& localport, const Socket__API__Definitions::ProtoTuple& proto, const int& userData); void sendConnClosed(const Socket__API__Definitions::ConnectionId& id, const CHARSTRING& remoteaddr, const Socket__API__Definitions::PortNumber& remoteport, const CHARSTRING& localaddr, const Socket__API__Definitions::PortNumber& localport, const Socket__API__Definitions::ProtoTuple& proto, const int& userData); int sendNonBlocking(const Socket__API__Definitions::ConnectionId& id, sockaddr *sa, socklen_t saLen, SockType type, const OCTETSTRING& msg, Socket__API__Definitions::Result& result, const Socket__API__Definitions::ProtoTuple& protoTuple = (const Socket__API__Definitions::ProtoTuple&)Socket__API__Definitions::ProtoTuple().unspecified()); bool getAndCheckSockType(int connId, Socket__API__Definitions::ProtoTuple::union_selection_type proto, SockType& type); bool setOptions(const IPL4asp__Types::OptionList& options, int sock, const Socket__API__Definitions::ProtoTuple& proto, bool beforeBind = false); int getOption(const IPL4asp__Types::Option& option, int sock, const Socket__API__Definitions::ProtoTuple& proto, bool beforeBind = false); void set_ssl_supp_option(const int& conn_id, const IPL4asp__Types::OptionList& options); void set_dscp_option(int sock); inline void testIfInitialized() const; void setResult(Socket__API__Definitions::Result& result, Socket__API__Definitions::PortError code, const Socket__API__Definitions::ConnectionId& id, int os_error_code = 0); void reportConnOpened(const int client_id); int backlog; bool pureNonBlocking; bool send_extended_result; int poll_timeout; int max_num_of_poll; GlobalConnOpts globalConnOpts; Socket__API__Definitions::f__getMsgLen defaultGetMsgLen; Socket__API__Definitions::f__getMsgLen defaultGetMsgLen_forConnClosedEvent; Socket__API__Definitions::ro__integer *defaultMsgLenArgs; Socket__API__Definitions::ro__integer *defaultMsgLenArgs_forConnClosedEvent; unsigned int sockListCnt; unsigned int sockListSize; int lonely_conn_id; int firstFreeSock; int lastFreeSock; bool broadcast; bool ssl_cert_per_conn; int lazy_conn_id_level; int sctp_PMTU_size; public: #ifdef USE_SCTP struct sctp_initmsg initmsg; struct sctp_event_subscribe events; #endif bool native_stack; #ifdef USE_IPL4_EIN_SCTP int verify_and_set_connid(ULONG_T ulpKey, ULONG_T assocId); CHARSTRING cpManagerIPA; int pipe_to_TTCN_thread_fds[2]; int pipe_to_TTCN_thread_log_fds[2]; int pipe_to_EIN_thread_fds[2]; void create_pipes(); void destroy_pipes(); void read_pipe(int pipe_fds[]); void write_pipe(int pipe_fds[]); void log_msg(const char *header, const MSG_T *msg); void log_thread(TTCN_Logger::Severity severity, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); void log_thread_msg(const char *header, const MSG_T *msg); static IPL4asp__PT_PROVIDER *port_ptr; pthread_t thread; void start_thread(); void do_bind(); void do_unbind(); //Internal commmunication between threads static void *thread_main(void *arg); void ein_receive_loop(); // State indicators boolean ein_connected; boolean thread_started; boolean unlinkingGT; boolean exiting; UCHAR_T bindResult; UCHAR_T sctpInstanceId; UCHAR_T userInstanceId; boolean userInstanceIdSpecified; boolean sctpInstanceIdSpecified; enum code_set {API_RETURN_CODES, CONF_RETURNCODE} ; const char *get_ein_sctp_error_message(const USHORT_T value, const code_set code_set_spec); USHORT_T userId; void handle_message_from_ein(int fd); std::map ep2IndexMap; Socket__API__Definitions::Result Listen_einsctp(const IPL4asp__Types::HostName& locName, const IPL4asp__Types::PortNumber& locPort, int next_action , const IPL4asp__Types::HostName& remName, const IPL4asp__Types::PortNumber& remPort, const IPL4asp__Types::OptionList& options, const IPL4asp__Types::SocketList &sock_list); int ConnAddEin(SockType type, int assoc_enpoint, int parentIdx, const IPL4asp__Types::HostName& locName, const IPL4asp__Types::PortNumber& locPort,const IPL4asp__Types::HostName& remName, const IPL4asp__Types::PortNumber& remPort, int next_action); int ConnDelEin(int connId,bool forced=false); USHORT_T SctpInitializeConf( UCHAR_T returnCode, ULONG_T sctpEndpointId, USHORT_T assignedMis, USHORT_T assignedOsServerMode, USHORT_T maxOs, ULONG_T pmtu, ULONG_T mappingKey, USHORT_T localPort ); USHORT_T SctpAssociateConf( UCHAR_T returnCode, ULONG_T assocId, ULONG_T ulpKey ); USHORT_T SctpCommUpInd( ULONG_T sctpEndpointId, ULONG_T assocId, ULONG_T ulpKey, UCHAR_T origin, USHORT_T outboundStreams, USHORT_T inboundStreams, USHORT_T remotePort, UCHAR_T numOfRemoteIpAddrs, IPADDRESS_T * remoteIpAddrList_sp ); USHORT_T SctpDataArriveInd( ULONG_T assocId, USHORT_T streamId, ULONG_T ulpKey, ULONG_T payloadProtId, BOOLEAN_T unorderFlag, USHORT_T streamSequenceNumber, UCHAR_T partialDeliveryFlag, ULONG_T dataLength, UCHAR_T * data_p ); USHORT_T SctpCommLostInd( ULONG_T assocId, ULONG_T ulpKey, UCHAR_T eventType, UCHAR_T origin ); USHORT_T SctpAssocRestartInd( ULONG_T assocId, ULONG_T ulpKey, USHORT_T outboundStreams, USHORT_T inboundStreams, UCHAR_T numOfRemoteIpAddrs, IPADDRESS_T * remoteIpAddrList_sp ); USHORT_T SctpCommErrorInd( ULONG_T assocId, ULONG_T ulpKey, UCHAR_T errorCode ); USHORT_T SctpShutdownConf( UCHAR_T returnCode, ULONG_T assocId, ULONG_T ulpKey ); USHORT_T SctpCongestionCeaseInd( ULONG_T assocId, ULONG_T ulpKey ); USHORT_T SctpSendFailureInd( UCHAR_T returnCode, ULONG_T assocId, ULONG_T ulpKey, ULONG_T dataLength, UCHAR_T * data_p, ULONG_T payloadProtId, USHORT_T streamId, ULONG_T userSequence, IPADDRESS_T * remoteIpAddr_s, BOOLEAN_T unorderFlag ); USHORT_T SctpNetworkStatusChangeInd( ULONG_T assocId, ULONG_T ulpKey, UCHAR_T newStatus, IPADDRESS_T remoteIpAddr_s ); USHORT_T SctpIndError( USHORT_T errorCode, MSG_T * msg_sp ); USHORT_T SctpBindConf( EINSS7INSTANCE_T sctpInstanceId, UCHAR_T error ); USHORT_T SctpStatusConf( UCHAR_T returnCode, ULONG_T mappingKey, ULONG_T sctpEndpointId, ULONG_T numOfAssociations, ASSOC_T * assocStatusList_sp ); USHORT_T SctpTakeoverConf( UCHAR_T returnCode, ULONG_T assocId, ULONG_T sctpEndpointId ); USHORT_T SctpTakeoverInd( UCHAR_T returnCode, ULONG_T assocId, ULONG_T sctpEndpointId ); USHORT_T SctpCongestionInd( ULONG_T assocId, ULONG_T ulpKey ); #endif std::map fd2IndexMap; bool mapped; bool debugAllowed; bool alreadyComplainedAboutMsgLen; Socket__API__Definitions::ConnectionId dontCloseConnectionId; SockAddr closingPeer; socklen_t closingPeerLen; friend void f__IPL4__PROVIDER__setGetMsgLen( IPL4asp__PT_PROVIDER& portRef, const Socket__API__Definitions::ConnectionId& connId, Socket__API__Definitions::f__getMsgLen& f, const Socket__API__Definitions::ro__integer& msgLenArgs); friend void f__IPL4__PROVIDER__setGetMsgLen__forConnClosedEvent( IPL4asp__PT_PROVIDER& portRef, const Socket__API__Definitions::ConnectionId& connId, Socket__API__Definitions::f__getMsgLen& f, const Socket__API__Definitions::ro__integer& msgLenArgs); friend Socket__API__Definitions::Result f__IPL4__PROVIDER__listen( IPL4asp__PT_PROVIDER& portRef, const Socket__API__Definitions::HostName& locName, const Socket__API__Definitions::PortNumber& locPort, const Socket__API__Definitions::ProtoTuple& proto, const IPL4asp__Types::OptionList& options); friend Socket__API__Definitions::Result f__IPL4__PROVIDER__connect( IPL4asp__PT_PROVIDER& portRef, const Socket__API__Definitions::HostName& remName, const Socket__API__Definitions::PortNumber& remPort, const Socket__API__Definitions::HostName& locName, const Socket__API__Definitions::PortNumber& locPort, const Socket__API__Definitions::ConnectionId& connId, const Socket__API__Definitions::ProtoTuple& proto, const IPL4asp__Types::OptionList& options); friend Socket__API__Definitions::Result f__IPL4__PROVIDER__setOpt( IPL4asp__PT_PROVIDER& portRef, const IPL4asp__Types::OptionList& options, const Socket__API__Definitions::ConnectionId& connId, const Socket__API__Definitions::ProtoTuple& proto); friend Socket__API__Definitions::Extended__Result f__IPL4__PROVIDER__getOpt( IPL4asp__PT_PROVIDER& portRef, const IPL4asp__Types::Option& option, const Socket__API__Definitions::ConnectionId& connId, const Socket__API__Definitions::ProtoTuple& proto); friend Socket__API__Definitions::Result f__IPL4__PROVIDER__close( IPL4asp__PT_PROVIDER& portRef, const Socket__API__Definitions::ConnectionId& id, const Socket__API__Definitions::ProtoTuple& proto); friend Socket__API__Definitions::Result f__IPL4__PROVIDER__setUserData( IPL4asp__PT_PROVIDER& portRef, const Socket__API__Definitions::ConnectionId& id, const Socket__API__Definitions::UserData& userData); friend Socket__API__Definitions::Result f__IPL4__PROVIDER__getUserData( IPL4asp__PT_PROVIDER& portRef, const Socket__API__Definitions::ConnectionId& id, Socket__API__Definitions::UserData& userData); friend Socket__API__Definitions::Result f__IPL4__PROVIDER__getConnectionDetails( IPL4asp__PT_PROVIDER& portRef, const Socket__API__Definitions::ConnectionId& id, const IPL4asp__Types::IPL4__Param& IPL4param, IPL4asp__Types::IPL4__ParamResult& IPL4paramResult); friend Socket__API__Definitions::Extended__Result f__IPL4__PROVIDER__getConnectedMTU( IPL4asp__PT_PROVIDER& portRef, const Socket__API__Definitions::ConnectionId& connId, const Socket__API__Definitions::ProtoTuple& proto); friend Socket__API__Definitions::Result f__IPL4__PROVIDER__StartTLS( IPL4asp__PT_PROVIDER& portRef, const IPL4asp__Types::ConnectionId& connId, const BOOLEAN& server__side); friend Socket__API__Definitions::Result f__IPL4__PROVIDER__StopTLS( IPL4asp__PT_PROVIDER& portRef, const IPL4asp__Types::ConnectionId& connId); friend OCTETSTRING f__IPL4__PROVIDER__exportTlsKey( IPL4asp__PT_PROVIDER& portRef, const IPL4asp__Types::ConnectionId& connId, const CHARSTRING& label, const OCTETSTRING& context, const INTEGER& keyLen); friend IPL4asp__Types::IPL4__SrtpKeysAndSalts f__IPL4__PROVIDER__exportSrtpKeysAndSalts( IPL4asp__PT_PROVIDER& portRef, const IPL4asp__Types::ConnectionId& connId); friend OCTETSTRING f__IPL4__PROVIDER__exportSctpKey( IPL4asp__PT_PROVIDER& portRef, const IPL4asp__Types::ConnectionId& connId); friend CHARSTRING f__IPL4__PROVIDER__getLocalCertificateFingerprint( IPL4asp__PT_PROVIDER& portRef, const IPL4asp__Types::IPL4__DigestMethods& method, const IPL4asp__Types::ConnectionId& connId); friend CHARSTRING f__IPL4__PROVIDER__getPeerCertificateFingerprint( IPL4asp__PT_PROVIDER& portRef, const IPL4asp__Types::ConnectionId& connId, const IPL4asp__Types::IPL4__DigestMethods& method); friend CHARSTRING f__IPL4__PROVIDER__getSelectedSrtpProfile( IPL4asp__PT_PROVIDER& portRef, const IPL4asp__Types::ConnectionId& connId); //SSL bool ssl_verify_certificate; // verify other part's certificate or not bool ssl_initialized; // whether SSL already initialized or not bool ssl_use_session_resumption; // use SSL sessions or not int ssl_reconnect_attempts;// maximum reconnect attempts, by default 5 (used only if pureNonBlocking is NOT used) int ssl_reconnect_delay; // delay between reconnect attempts, by default 1 (used only if pureNonBlocking is NOT used) char *ssl_key_file; // private key file char *ssl_certificate_file; // own certificate file char *ssl_trustedCAlist_file; // trusted CA list file char *ssl_cipher_list; // ssl_cipher list restriction to apply char *ssl_password; // password to decode the private key static const unsigned char * ssl_server_auth_session_id_context; char *psk_identity; char *psk_identity_hint; char *psk_key; #ifdef IPL4_USE_SSL // const SSL_METHOD *ssl_method; // SSL context method SSL_CTX *ssl_ctx; // SSL context SSL_CTX *ssl_dtls_server_ctx; // DTLS context SSL_CTX *ssl_dtls_client_ctx; // DTLS context // const SSL_CIPHER *ssl_cipher; // used SSL ssl_cipher SSL_SESSION *ssl_session; // SSL ssl_session SSL *ssl_current_ssl; // currently used SSL object static void *ssl_current_client; // current SSL object, used only during authentication bool ssl_actions_to_seed_PRNG(); // Seed the PRNG with enough random data bool ssl_init_SSL(int); // Initialize SSL libraries and create the SSL context bool ssl_init_SSL_ctx(SSL_CTX* in_ssl_ctx, int conn_id=-1); // Initialize each SSL context void ssl_log_SSL_info(); // Log the currently used SSL setting (debug) int ssl_getresult(int result_code); // Fetch and log the SSL error code from I/O operation result codes // Callback function to pass the password to OpenSSL. Called by OpenSSL // during SSL handshake. static int ssl_password_cb(char * password_buffer, int length_of_password, int rw_flag, void * user_data); // Callback function to perform authentication during SSL handshake. Called by OpenSSL. // NOTE: for further authentication, use ssl_verify_certificates(). static int ssl_verify_callback(int preverify_status, X509_STORE_CTX * ssl_context); #endif }; #ifdef EIN_R3B USHORT_T EINSS7_00SCTPSETEPALIASCONF( UCHAR_T returnCode, ULONG_T sctpEndpointId, ULONG_T epAlias ); USHORT_T EINSS7_00SCTPSETUSERCONGESTIONLEVELCONF ( UCHAR_T returnCode, ULONG_T epAlias, UCHAR_T congestionLevel, ULONG_T numberOfAffectedEndpoints ); USHORT_T EINSS7_00SCTPGETUSERCONGESTIONLEVELCONF ( UCHAR_T returnCode, ULONG_T epAlias, UCHAR_T congestionLevel ); UINT16_T EINSS7_00SCTPREDIRECTIND ( UINT8_T action, UINT16_T oldSctpFeInstance, UINT16_T newSctpFeInstance ); UINT16_T EINSS7_00SCTPINFOCONF ( UINT8_T result, UINT8_T reservedByte, UINT8_T partialDeliveryFlag, UINT32_T mappingKey, EINSS7_00SCTP_INFO_TAG_T * topTag ); UINT16_T EINSS7_00SCTPINFOIND ( UINT8_T reservedByte1, UINT8_T reservedByte2, UINT8_T partialDeliveryFlag, UINT32_T mappingKey, EINSS7_00SCTP_INFO_TAG_T * topTag ); UINT16_T EINSS7_00SCTPUPDATECONF ( UINT8_T result, UINT8_T reservedByte, UINT8_T partialDeliveryFlag, UINT32_T mappingKey, EINSS7_00SCTP_INFO_TAG_T * topTag ); #endif int SetLocalSockAddr(const char* debug_str, IPL4asp__PT_PROVIDER& portRef, int def_addr_family, const char *locName, int locPort, SockAddr& sockAddr, socklen_t& sockAddrLen); } /*end of namespace*/ #endif