/* Copyright (C) 2005-2009 Michel de Boer 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, see . */ #ifndef _STUN_TRANSACTION_H #define _STUN_TRANSACTION_H #include "stun.h" #include "phone_user.h" #include "protocol.h" #include "user.h" #include "transaction.h" #include "threads/mutex.h" #include "threads/thread.h" #include "sockets/socket.h" #include "sockets/url.h" // Create a binding in a NAT. // Returns true on success. Returns false when the STUN server returned // an error. Throws an int exception (containing errno) when some // socket operation fails. bool get_stun_binding(t_user *user_config, unsigned short src_port, unsigned long &mapped_ip, unsigned short &mapped_port, int &err_code, string &err_reason); // Discover the type of NAT and determine is STUN should be used or // wether STUN is useless. // It sets the use_stun attribute of phone if STUN should be used. // Return false if STUN cannot be used. err_msg will contain an // error message that can be displayed to the user. bool stun_discover_nat(t_phone_user *pu, string &err_msg); ////////////////////////////////////////////// // Base STUN transaction ////////////////////////////////////////////// class t_stun_transaction { private: static t_mutex mtx_class; // protect static members static t_tid next_id; // next id to be issued protected: t_tid id; // transaction id unsigned short tuid; // TU id t_trans_state state; // Timer for retransmissions unsigned short timer_req_timeout; // Duration for the next timer start in msec unsigned long dur_req_timeout; // Number of transmissions of the request unsigned short num_transmissions; // Destinations for the request list destinations; // User profile of user that created this transaction t_user *user_config; void start_timer_req_timeout(void); void stop_timer_req_timeout(void); // Retransmit STUN request virtual void retransmit(void) = 0; public: StunMessage *request; t_tid get_id(void) const; // Get state of the transaction t_trans_state get_state(void) const; // The transaction will keep a copy of the request t_stun_transaction(t_user *user, StunMessage *r, unsigned short _tuid, const list &dst); // All request and response pointers contained by the // transaction will be deleted. virtual ~t_stun_transaction(); // Process STUN response virtual void process_response(StunMessage *r); // Process ICMP error virtual void process_icmp(const t_icmp_msg &icmp); // Process timeout virtual void timeout(t_stun_timer t); // Match response with transaction bool match(StunMessage *resp) const; // Match ICMP error with transaction bool match(const t_icmp_msg &icmp) const; }; ////////////////////////////////////////////// // SIP STUN transaction ////////////////////////////////////////////// // A SIP STUN transaction is a STUN request to get a binding // for the SIP port. Such a request must be sent from the SIP port. // So it must be sent out via the SIP sender thread. class t_sip_stun_trans : public t_stun_transaction { protected: virtual void retransmit(void); public: // Create transaction and send out STUN request t_sip_stun_trans(t_user *user, StunMessage *r, unsigned short _tuid, const list &dst); }; ////////////////////////////////////////////// // Media STUN transaction ////////////////////////////////////////////// // TODO: this code is not used anymore. Remove? // A media STUN transaction is a STUN request to get a binding // for a media port. Such a request must be sent from the media // port. class t_media_stun_trans : public t_stun_transaction { private: t_socket_udp *sock; // UDP socket for STUN t_thread *thr_listen; // Listener thread protected: virtual void retransmit(void); public: // Create transaction and send out STUN request t_media_stun_trans(t_user *user, StunMessage *r, unsigned short _tuid, const list &dst, unsigned short src_port); ~t_media_stun_trans(); }; #endif