/* * 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 * * Author : Richard GAYRAUD - 04 Nov 2003 * From Hewlett Packard Company. */ #ifndef __SIPP__ #define __SIPP__ /* Std C includes */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(__HPUX) || defined(__SUNOS) #include #endif /* Sipp includes */ #include "xp_parser.h" #include "scenario.hpp" #include "screen.hpp" #include "call.hpp" #include "comp.h" #include "stat.hpp" #include "actions.hpp" #include "variables.hpp" #include "infile.hpp" /* Open SSL stuff */ #ifdef _USE_OPENSSL #include "sslcommon.h" #endif #ifndef __CYGWIN #ifndef FD_SETSIZE #define FD_SETSIZE 65000 #endif #else #ifndef FD_SETSIZE #define FD_SETSIZE 1024 #endif #endif /* * If this files is included in the Main, then extern definitions * are removed, and the _DEFAULT macro becomes '= value;'. Else * extern definition does not contain default values assignment */ #ifdef GLOBALS_FULL_DEFINITION #define extern #define _DEFVAL(value) = value #else #define _DEFVAL(value) #endif /************************** Constants **************************/ #define SIPP_VERSION 20071024 #define T_UDP 0 #define T_TCP 1 #define T_TLS 2 #ifdef _USE_OPENSSL #define DEFAULT_TLS_CERT ((char *)"cacert.pem") #define DEFAULT_TLS_KEY ((char *)"cakey.pem") #define DEFAULT_TLS_CRL ((char *)"") #endif #define TRANSPORT_TO_STRING(p) ((p==T_TCP) ? "TCP" : ((p==T_TLS)? "TLS" :"UDP")) #define SIPP_MAXFDS 65536 #define SIPP_MAX_MSG_SIZE 65536 #define MSG_RETRANS_FIRST 0 #define MSG_RETRANS_RETRANSMISSION 1 #define MSG_RETRANS_NEVER 2 #define DISPLAY_STAT_SCREEN 1 #define DISPLAY_REPARTITION_SCREEN 2 #define DISPLAY_SCENARIO_SCREEN 3 #define DISPLAY_VARIABLE_SCREEN 4 #define DISPLAY_TDM_MAP_SCREEN 5 #define DISPLAY_SECONDARY_REPARTITION_SCREEN 6 #define MAX_RECV_LOOPS_PER_CYCLE 1000 #define MAX_SCHED_LOOPS_PER_CYCLE 1000 #define NB_UPDATE_PER_CYCLE 1 #define MAX_PATH 250 #define MAX_PEER_SIZE 4096 /* 3pcc extended mode: max size of peer names */ #define MAX_LOCAL_TWIN_SOCKETS 10 /*3pcc extended mode:max number of peers from which cmd messages are received */ /******************** Default parameters ***********************/ #define DEFAULT_RATE 10.0 #define DEFAULT_RATE_PERIOD_MS 1000 #define DEFAULT_TRANSPORT T_UDP #define DEFAULT_PORT 5060 #define DEFAULT_MEDIA_PORT 6000 #ifdef __3PCC__ #define DEFAULT_3PCC_PORT 6060 #endif #define DEFAULT_SERVICE ((char *)"service") #define DEFAULT_AUTH_PASSWORD ((char *)"password") #define DEFAULT_REPORT_FREQ 1000 #define DEFAULT_REPORT_FREQ_DUMP_LOG 60000 #define DEFAULT_TIMER_RESOLUTION 1 #define DEFAULT_FREQ_DUMP_RTT 200 #define DEFAULT_MAX_MULTI_SOCKET 50000 #define DEFAULT_CTRL_SOCKET_PORT 8888 /************ User controls and command line options ***********/ extern int duration _DEFVAL(0); extern double rate _DEFVAL(DEFAULT_RATE); extern int rate_increase _DEFVAL(0); extern int rate_max _DEFVAL(0); extern int users _DEFVAL(0); extern int rate_period_ms _DEFVAL(DEFAULT_RATE_PERIOD_MS); extern unsigned long defl_recv_timeout _DEFVAL(0); extern unsigned long defl_send_timeout _DEFVAL(0); extern unsigned long global_timeout _DEFVAL(0); extern int transport _DEFVAL(DEFAULT_TRANSPORT); extern bool retrans_enabled _DEFVAL(1); extern int max_udp_retrans _DEFVAL(UDP_MAX_RETRANS); extern int max_invite_retrans _DEFVAL(UDP_MAX_RETRANS_INVITE_TRANSACTION); extern int max_non_invite_retrans _DEFVAL(UDP_MAX_RETRANS_NON_INVITE_TRANSACTION); extern bool default_behavior _DEFVAL(1); extern bool pause_msg_ign _DEFVAL(0); extern int auto_answer _DEFVAL(0); extern int multisocket _DEFVAL(0); extern int compression _DEFVAL(0); extern int peripsocket _DEFVAL(0); extern int peripfield _DEFVAL(0); extern int bind_local _DEFVAL(0); extern void * monosocket_comp_state _DEFVAL(0); extern char * service _DEFVAL(DEFAULT_SERVICE); extern char * auth_password _DEFVAL(DEFAULT_AUTH_PASSWORD); extern unsigned long report_freq _DEFVAL(DEFAULT_REPORT_FREQ); extern unsigned long report_freq_dumpLog _DEFVAL (DEFAULT_REPORT_FREQ_DUMP_LOG); extern char * stat_delimiter _DEFVAL(";"); extern bool timeout_exit _DEFVAL(false); extern unsigned long report_freq_dumpRtt _DEFVAL (DEFAULT_FREQ_DUMP_RTT); extern unsigned int max_multi_socket _DEFVAL (DEFAULT_MAX_MULTI_SOCKET); extern unsigned int timer_resolution _DEFVAL(DEFAULT_TIMER_RESOLUTION); extern int max_recv_loops _DEFVAL(MAX_RECV_LOOPS_PER_CYCLE); extern int max_sched_loops _DEFVAL(MAX_SCHED_LOOPS_PER_CYCLE); extern char local_ip[40]; extern char local_ip_escaped[42]; extern bool local_ip_is_ipv6; extern int local_port _DEFVAL(0); extern int control_port _DEFVAL(0); extern int buff_size _DEFVAL(65535); extern int tcp_readsize _DEFVAL(65535); #ifdef PCAPPLAY extern int hasMedia _DEFVAL(0); #endif extern bool rtp_echo_enabled _DEFVAL(0); extern char media_ip[40]; extern char media_ip_escaped[42]; extern int user_media_port _DEFVAL(0); extern int media_port _DEFVAL(0); extern size_t media_bufsize _DEFVAL(2048); extern bool media_ip_is_ipv6; extern char remote_ip[40]; extern char remote_ip_escaped[42]; extern int remote_port _DEFVAL(DEFAULT_PORT); extern unsigned int pid _DEFVAL(0); extern int print_all_responses _DEFVAL(0); extern unsigned long stop_after _DEFVAL(0xffffffff); extern int quitting _DEFVAL(0); extern int interrupt _DEFVAL(0); extern int paused _DEFVAL(0); extern int lose_packets _DEFVAL(0); extern double global_lost _DEFVAL(0.0); extern char remote_host[255]; #ifdef __3PCC__ extern char twinSippHost[255]; extern char twinSippIp[40]; extern char * master_name; extern char * slave_number; extern int twinSippPort _DEFVAL(DEFAULT_3PCC_PORT); extern bool twinSippMode _DEFVAL(false); extern bool extendedTwinSippMode _DEFVAL(false); #endif extern bool backgroundMode _DEFVAL(false); extern bool signalDump _DEFVAL(false); extern int currentScreenToDisplay _DEFVAL (DISPLAY_SCENARIO_SCREEN); extern int currentRepartitionToDisplay _DEFVAL(1); extern unsigned int base_cseq _DEFVAL(0); extern char * auth_uri _DEFVAL(0); extern char * call_id_string _DEFVAL("%u-%p@%s"); extern char **generic[100]; /* TDM map */ extern bool use_tdmmap _DEFVAL(false); extern unsigned int tdm_map_a _DEFVAL(0); extern unsigned int tdm_map_b _DEFVAL(0); extern unsigned int tdm_map_c _DEFVAL(0); extern unsigned int tdm_map_x _DEFVAL(0); extern unsigned int tdm_map_y _DEFVAL(0); extern unsigned int tdm_map_z _DEFVAL(0); extern unsigned int tdm_map_h _DEFVAL(0); extern bool tdm_map[1024]; #ifdef _USE_OPENSSL extern BIO *twinSipp_bio ; extern SSL *twinSipp_ssl ; extern char *tls_cert_name _DEFVAL(DEFAULT_TLS_CERT) ; extern char *tls_key_name _DEFVAL(DEFAULT_TLS_KEY) ; extern char *tls_crl_name _DEFVAL(DEFAULT_TLS_CRL) ; #endif // extern field file management typedef std::map file_map; extern file_map inFiles; extern char *ip_file _DEFVAL(NULL); extern char *default_file _DEFVAL(NULL); // free user id list extern list freeUsers; //extern int new_socket(bool P_use_ipv6, int P_type_socket, int * P_status); extern struct sipp_socket *new_sipp_socket(bool use_ipv6, int transport); struct sipp_socket *new_sipp_call_socket(bool use_ipv6, int transport, bool *existing); struct sipp_socket *sipp_accept_socket(struct sipp_socket *accept_socket); extern int sipp_bind_socket(struct sipp_socket *socket, struct sockaddr_storage *saddr, int *port); extern int sipp_connect_socket(struct sipp_socket *socket, struct sockaddr_storage *dest); extern void sipp_customize_socket(struct sipp_socket *socket); extern int delete_socket(int P_socket); extern int min_socket _DEFVAL(65535); extern int select_socket _DEFVAL(0); extern bool socket_close _DEFVAL(true); extern bool test_socket _DEFVAL(true); extern bool maxSocketPresent _DEFVAL(false); extern unsigned long getmilliseconds(); extern unsigned long long getmicroseconds(); /************************ Statistics **************************/ extern unsigned long total_calls _DEFVAL(0); extern unsigned long last_report_calls _DEFVAL(0); extern unsigned long nb_net_send_errors _DEFVAL(0); extern unsigned long nb_net_cong _DEFVAL(0); extern unsigned long nb_net_recv_errors _DEFVAL(0); extern bool cpu_max _DEFVAL(false); extern bool outbound_congestion _DEFVAL(false); extern unsigned int open_calls_peak _DEFVAL(0); extern unsigned long open_calls_peak_time _DEFVAL(0); extern int open_calls_user_setting _DEFVAL(0); extern int nb_out_of_the_blue _DEFVAL(0); extern int resynch_send _DEFVAL(0); extern int resynch_recv _DEFVAL(0); extern unsigned long rtp_pckts _DEFVAL(0); extern unsigned long rtp_bytes _DEFVAL(0); extern unsigned long rtp_pckts_pcap _DEFVAL(0); extern unsigned long rtp_bytes_pcap _DEFVAL(0); extern unsigned long rtp2_pckts _DEFVAL(0); extern unsigned long rtp2_bytes _DEFVAL(0); extern unsigned long rtp2_pckts_pcap _DEFVAL(0); extern unsigned long rtp2_bytes_pcap _DEFVAL(0); /************* Rate Control & Contexts variables **************/ extern unsigned int open_calls _DEFVAL(0); extern int last_running_calls _DEFVAL(0); extern int last_woken_calls _DEFVAL(0); extern int last_paused_calls _DEFVAL(0); extern unsigned int open_calls_allowed _DEFVAL(0); extern unsigned long last_rate_change_time _DEFVAL(0); extern unsigned long last_report_time _DEFVAL(0); extern unsigned long last_dump_time _DEFVAL(0); extern unsigned long calls_since_last_rate_change _DEFVAL(0); /********************** Clock variables ***********************/ extern unsigned long clock_tick _DEFVAL(0); extern unsigned long scheduling_loops _DEFVAL(0); extern unsigned long last_timer_cycle _DEFVAL(0); #define GET_TIME(clock) \ { \ struct timezone tzp; \ gettimeofday (clock, &tzp); \ } /*********************** Global Sockets **********************/ extern struct sipp_socket *main_socket _DEFVAL(0); extern struct sipp_socket *tcp_multiplex _DEFVAL(0); extern int media_socket _DEFVAL(0); extern int media_socket_video _DEFVAL(0); extern struct sockaddr_storage local_sockaddr; extern struct sockaddr_storage localTwin_sockaddr; extern int user_port _DEFVAL(0); extern char hostname[80]; extern bool is_ipv6 _DEFVAL(false); extern int start_calls _DEFVAL(0); extern int reset_number _DEFVAL(0); extern int reset_close _DEFVAL(1); extern int reset_sleep _DEFVAL(1000); extern struct addrinfo * local_addr_storage; extern struct sipp_socket *twinSippSocket _DEFVAL(NULL); extern struct sipp_socket *localTwinSippSocket _DEFVAL(NULL); extern struct sockaddr_storage twinSipp_sockaddr; /* 3pcc extended mode */ typedef struct _T_peer_infos { char peer_host[40]; int peer_port; struct sockaddr_storage peer_sockaddr; char peer_ip[40]; struct sipp_socket *peer_socket ; } T_peer_infos; typedef std::map peer_addr_map; extern peer_addr_map peer_addrs; typedef std::map peer_map; extern peer_map peers; typedef std::map peer_socket_map; extern peer_socket_map peer_sockets; extern struct sipp_socket *local_sockets[MAX_LOCAL_TWIN_SOCKETS]; extern int local_nb _DEFVAL(0); extern int peers_connected _DEFVAL(0); extern struct sockaddr_storage remote_sockaddr; extern short use_remote_sending_addr _DEFVAL(0); extern struct sockaddr_storage remote_sending_sockaddr; enum E_Alter_YesNo { E_ALTER_YES=0, E_ALTER_NO }; /************************** Trace Files ***********************/ extern FILE * screenf _DEFVAL(0); extern FILE * logfile _DEFVAL(0); extern FILE * messagef _DEFVAL(0); extern FILE * shortmessagef _DEFVAL(0); // extern FILE * timeoutf _DEFVAL(0); extern bool useMessagef _DEFVAL(0); extern bool useShortMessagef _DEFVAL(0); extern bool useScreenf _DEFVAL(0); extern bool useLogf _DEFVAL(0); //extern bool useTimeoutf _DEFVAL(0); extern bool dumpInFile _DEFVAL(0); extern bool dumpInRtt _DEFVAL(0); extern char * scenario_file; extern char * slave_cfg_file; #define TRACE_MSG(arg) \ { \ if(messagef) { \ FILE * s = messagef; \ fprintf arg; \ fflush(messagef); \ } \ } #define TRACE_SHORTMSG(arg) \ { \ if(shortmessagef) { \ FILE * s = shortmessagef;\ fprintf arg; \ fflush(shortmessagef); \ } \ } #define LOG_MSG(arg) \ { \ if(logfile) { \ FILE * s = logfile; \ fprintf arg; \ fflush(logfile); \ } \ } // TODO: finish the -trace_timeout option implementation /* #define TRACE_TIMEOUT(arg) \ { \ if(timeoutf) { \ FILE * s = timeoutf; \ fprintf arg; \ fflush(timeoutf); \ } \ } */ /********************* Mini-Parser Routines *******************/ int get_method(char *msg); char * get_peer_tag(char *msg); unsigned long int get_cseq_value(char *msg); unsigned long get_reply_code(char *msg); /********************** Network Interfaces ********************/ int send_message(int s, void ** comp_state, char * msg); #ifdef _USE_OPENSSL int send_message_tls(SSL *s, void ** comp_state, char * msg); #endif /* Socket Buffer Management. */ #define NO_COPY 0 #define DO_COPY 1 struct socketbuf *alloc_socketbuf(char *buffer, size_t size, int copy); void free_socketbuf(struct socketbuf *socketbuf); /* These buffers lets us read past the end of the message, and then split it if * required. This eliminates the need for reading a message octet by octet and * performing a second read for the content length. */ struct socketbuf { char *buf; size_t len; size_t offset; struct socketbuf *next; }; /* This is an abstraction of a socket, which provides buffers for input and * output. */ struct sipp_socket { int ss_count; /* How many users are there of this socket? */ int ss_transport; /* T_TCP, T_UDP, or T_TLS. */ bool ss_ipv6; bool ss_control; /* Is this a control socket? */ bool ss_call_socket; /* Is this a call socket? */ int ss_fd; /* The underlying file descriptor for this socket. */ void *ss_comp_state; /* The compression state. */ #ifdef _USE_OPENSSL SSL *ss_ssl; /* The underlying SSL descriptor for this socket. */ BIO *ss_bio; /* The underlying BIO descriptor for this socket. */ #endif struct sockaddr_storage ss_remote_sockaddr; /* Who we are talking to. */ int ss_pollidx; /* The index of this socket in our poll structures. */ bool ss_congested; /* Is this socket congested? */ bool ss_invalid; /* Has this socket been closed remotely? */ struct socketbuf *ss_in; /* Buffered input. */ size_t ss_msglen; /* Is there a complete SIP message waiting, and if so how big? */ struct socketbuf *ss_out; /* Buffered output. */ }; /* Write data to a socket. */ int write_socket(struct sipp_socket *socket, char *buffer, ssize_t len, int flags); /* Mark a socket as "bad". */ void sipp_socket_invalidate(struct sipp_socket *socket); /* Actually free the socket. */ void sipp_close_socket(struct sipp_socket *socket); #define WS_EAGAIN 1 /* Return EAGAIN if there is no room for writing the message. */ #define WS_BUFFER 2 /* Buffer the message if there is no room for writing the message. */ #if defined (__hpux) || defined (__alpha) && !defined (__FreeBSD__) #define sipp_socklen_t int #else #define sipp_socklen_t socklen_t #endif #define SOCK_ADDR_SIZE(a) \ (((a)->ss_family == AF_INET) ? sizeof(struct sockaddr_in) \ : sizeof(struct sockaddr_in6)) #if defined(__cplusplus) && defined (__hpux) #define _RCAST(type, val) (reinterpret_cast (val)) #else #define _RCAST(type, val) ((type)(val)) #endif /********************* Utilities functions *******************/ char *strcasestr2 ( char *__haystack, char *__needle); char *get_peer_addr(char *); int get_decimal_from_hex(char hex); int reset_connections() ; int close_calls(); int close_calls(struct sipp_socket *); int close_connections(); int open_connections(); void timeout_alarm(int); /* extended 3PCC mode */ struct sipp_socket **get_peer_socket(char *); bool is_a_peer_socket(struct sipp_socket *); bool is_a_local_socket(struct sipp_socket *); void connect_to_peer (char *, int , sockaddr_storage *, char *, struct sipp_socket **); void connect_to_all_peers (); void connect_local_twin_socket(char *); void close_peer_sockets(); void close_local_sockets(); void free_peer_addr_map(); /********************* Reset global kludge *******************/ #ifdef GLOBALS_FULL_DEFINITION #undef extern #endif #endif // __SIPP__