| 1 | /// ----------------------------------------*- mode: C++; -*-- | 
|---|
| 2 | /// @file tp_over_udp.h | 
|---|
| 3 | /// Transport over UDP | 
|---|
| 4 | /// ---------------------------------------------------------- | 
|---|
| 5 | /// $Id: tp_over_udp.h 2718 2007-07-24 03:23:14Z bless $ | 
|---|
| 6 | /// $HeadURL: https://svn.ipv6.tm.uka.de/nsis/protlib/trunk/include/tp_over_udp.h $ | 
|---|
| 7 | // =========================================================== | 
|---|
| 8 | // | 
|---|
| 9 | // Copyright (C) 2005-2007, all rights reserved by | 
|---|
| 10 | // - Institute of Telematics, Universitaet Karlsruhe (TH) | 
|---|
| 11 | // | 
|---|
| 12 | // More information and contact: | 
|---|
| 13 | // https://projekte.tm.uka.de/trac/NSIS | 
|---|
| 14 | // | 
|---|
| 15 | // This program is free software; you can redistribute it and/or modify | 
|---|
| 16 | // it under the terms of the GNU General Public License as published by | 
|---|
| 17 | // the Free Software Foundation; version 2 of the License | 
|---|
| 18 | // | 
|---|
| 19 | // This program is distributed in the hope that it will be useful, | 
|---|
| 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 22 | // GNU General Public License for more details. | 
|---|
| 23 | // | 
|---|
| 24 | // You should have received a copy of the GNU General Public License along | 
|---|
| 25 | // with this program; if not, write to the Free Software Foundation, Inc., | 
|---|
| 26 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 
|---|
| 27 | // | 
|---|
| 28 | // =========================================================== | 
|---|
| 29 | /** @ingroup tpudp | 
|---|
| 30 | * @ file | 
|---|
| 31 | * TP over UDP | 
|---|
| 32 | */ | 
|---|
| 33 |  | 
|---|
| 34 | #ifndef TP_OVER_UDP_H | 
|---|
| 35 | #define TP_OVER_UDP_H | 
|---|
| 36 |  | 
|---|
| 37 | #include <boost/unordered_map.hpp> | 
|---|
| 38 |  | 
|---|
| 39 | #include "tp.h" | 
|---|
| 40 | #include "threads.h" | 
|---|
| 41 | #include "threadsafe_db.h" | 
|---|
| 42 | #include "connectionmap.h" | 
|---|
| 43 | #include "assocdata.h" | 
|---|
| 44 |  | 
|---|
| 45 | namespace protlib | 
|---|
| 46 | { | 
|---|
| 47 | /** this struct conatains parameters that determine | 
|---|
| 48 | * the behavior of listener and receiver threads in TPoverUDP | 
|---|
| 49 | * @param port - port number for master listener thread (server port) | 
|---|
| 50 | * @param sleep - time (in ms) that listener and receiver wait at a poll() call | 
|---|
| 51 | * @param d - destination module, where internal message are sent | 
|---|
| 52 | */ | 
|---|
| 53 | struct TPoverUDPParam : public ThreadParam | 
|---|
| 54 | { | 
|---|
| 55 | /// constructor | 
|---|
| 56 | TPoverUDPParam( | 
|---|
| 57 | unsigned short common_header_length, | 
|---|
| 58 | bool (*const getmsglength) (NetMsg& m, uint32& clen_words), | 
|---|
| 59 | port_t listen_port, | 
|---|
| 60 | uint32 sleep = ThreadParam::default_sleep_time, | 
|---|
| 61 | bool debug_pdu = false, | 
|---|
| 62 | message::qaddr_t source = message::qaddr_tp_over_udp, | 
|---|
| 63 | message::qaddr_t dest = message::qaddr_signaling, | 
|---|
| 64 | bool sendaborts = false, | 
|---|
| 65 | uint8 tos = 0x10) : | 
|---|
| 66 | ThreadParam(sleep,"TPoverUDP",1,1), | 
|---|
| 67 | port(listen_port), | 
|---|
| 68 | debug_pdu(debug_pdu), | 
|---|
| 69 | source(source), | 
|---|
| 70 | dest(dest), | 
|---|
| 71 | common_header_length(common_header_length), | 
|---|
| 72 | getmsglength(getmsglength), | 
|---|
| 73 | terminate(false), | 
|---|
| 74 | ip_tos(tos) | 
|---|
| 75 | {}; | 
|---|
| 76 |  | 
|---|
| 77 | /// port to bind master listener thread to | 
|---|
| 78 | const port_t port; | 
|---|
| 79 | bool debug_pdu; | 
|---|
| 80 | /// message source | 
|---|
| 81 | const message::qaddr_t source; | 
|---|
| 82 | const message::qaddr_t dest; | 
|---|
| 83 | /// what is the length of the common header | 
|---|
| 84 | const unsigned short common_header_length; | 
|---|
| 85 |  | 
|---|
| 86 | /// function pointer to a function that figures out the msg length in number of 4 byte words | 
|---|
| 87 | /// it returns false if error occured (e.g., malformed header), result is returned in variable clen_words | 
|---|
| 88 | bool (*const getmsglength) (NetMsg& m, uint32& clen_words); | 
|---|
| 89 |  | 
|---|
| 90 | /// should master thread terminate? | 
|---|
| 91 | const bool terminate; | 
|---|
| 92 | const uint8 ip_tos; | 
|---|
| 93 |  | 
|---|
| 94 | bool (*rao_lookup) (uint32); | 
|---|
| 95 |  | 
|---|
| 96 |  | 
|---|
| 97 | }; // end TPoverUDPParam | 
|---|
| 98 |  | 
|---|
| 99 |  | 
|---|
| 100 | /// TP over UDP | 
|---|
| 101 | /** This class implements the TP interface using UDP. */ | 
|---|
| 102 | class TPoverUDP : public TP, public Thread | 
|---|
| 103 | { | 
|---|
| 104 | /***** inherited from TP *****/ | 
|---|
| 105 | public: | 
|---|
| 106 | /// sends a network message, spawns receiver thread if necessary | 
|---|
| 107 | virtual void send(NetMsg* msg, const address& addr, bool use_existing_connection); | 
|---|
| 108 | virtual void terminate(const address& addr); | 
|---|
| 109 |  | 
|---|
| 110 | /***** inherited from Thread *****/ | 
|---|
| 111 | public: | 
|---|
| 112 | /// main loop | 
|---|
| 113 | virtual void main_loop(uint32 nr); | 
|---|
| 114 |  | 
|---|
| 115 | /***** other members *****/ | 
|---|
| 116 | public: | 
|---|
| 117 | /// constructor | 
|---|
| 118 | TPoverUDP(const TPoverUDPParam& p) : | 
|---|
| 119 | TP(tsdb::getprotobyname("udp"),"udp",p.name,p.common_header_length,p.getmsglength), | 
|---|
| 120 | Thread(p), tpparam(p), already_aborted(false), msgqueue(NULL), debug_pdu(p.debug_pdu), | 
|---|
| 121 | master_listener_socket(-1) | 
|---|
| 122 | { | 
|---|
| 123 | // perform some initializing actions | 
|---|
| 124 | // currently not required (SCTP had to init its library) | 
|---|
| 125 | init= true; ///< init done; | 
|---|
| 126 | } | 
|---|
| 127 | /// virtual destructor | 
|---|
| 128 | virtual ~TPoverUDP(); | 
|---|
| 129 |  | 
|---|
| 130 | class sender_thread_start_arg_t | 
|---|
| 131 | { | 
|---|
| 132 | public: | 
|---|
| 133 | TPoverUDP* instance; | 
|---|
| 134 | FastQueue* sender_thread_queue; | 
|---|
| 135 |  | 
|---|
| 136 | sender_thread_start_arg_t(TPoverUDP* instance, FastQueue* sq) : | 
|---|
| 137 | instance(instance), sender_thread_queue(sq) {}; | 
|---|
| 138 | }; | 
|---|
| 139 |  | 
|---|
| 140 | int get_listener_socket() const { return master_listener_socket; } | 
|---|
| 141 |  | 
|---|
| 142 | private: | 
|---|
| 143 |  | 
|---|
| 144 |  | 
|---|
| 145 | /// send a message to the network via UDP | 
|---|
| 146 | void udpsend(NetMsg* msg, appladdress* addr); | 
|---|
| 147 |  | 
|---|
| 148 | /// a static starter method to invoke the listener thread | 
|---|
| 149 | static void* listener_thread_starter(void *argp); | 
|---|
| 150 |  | 
|---|
| 151 | /// listener thread procedure | 
|---|
| 152 | void listener_thread(); | 
|---|
| 153 |  | 
|---|
| 154 | /// terminates all active receiver or sender threads | 
|---|
| 155 | void terminate_all_threads(); | 
|---|
| 156 |  | 
|---|
| 157 | /// parameters for main TPoverUDP thread | 
|---|
| 158 | const TPoverUDPParam tpparam; | 
|---|
| 159 |  | 
|---|
| 160 | /// did we already abort at thread shutdown | 
|---|
| 161 | bool already_aborted; | 
|---|
| 162 | /// message queue | 
|---|
| 163 | FastQueue* msgqueue; | 
|---|
| 164 |  | 
|---|
| 165 | bool debug_pdu; | 
|---|
| 166 |  | 
|---|
| 167 | int master_listener_socket; | 
|---|
| 168 |  | 
|---|
| 169 | }; // end class TPoverUDP | 
|---|
| 170 |  | 
|---|
| 171 | /** A simple internal message for selfmessages | 
|---|
| 172 | * please note that carried items may get deleted after use of this message | 
|---|
| 173 | * the message destructor does not delete any item automatically | 
|---|
| 174 | */ | 
|---|
| 175 | class TPoverUDPMsg : public message | 
|---|
| 176 | { | 
|---|
| 177 | public: | 
|---|
| 178 | // message type start/stop thread, send data | 
|---|
| 179 | enum msg_t { start, | 
|---|
| 180 | stop, | 
|---|
| 181 | send_data | 
|---|
| 182 | }; | 
|---|
| 183 |  | 
|---|
| 184 | private: | 
|---|
| 185 | const AssocData* peer_assoc; | 
|---|
| 186 | const TPoverUDPMsg::msg_t type; | 
|---|
| 187 | NetMsg* netmsg; | 
|---|
| 188 | appladdress* addr; | 
|---|
| 189 |  | 
|---|
| 190 | public: | 
|---|
| 191 | TPoverUDPMsg(const AssocData* peer_assoc, message::qaddr_t source= qaddr_unknown, TPoverUDPMsg::msg_t type= stop) : | 
|---|
| 192 | message(type_transport, source), peer_assoc(peer_assoc), type(type), netmsg(0), addr(0)  {} | 
|---|
| 193 |  | 
|---|
| 194 | TPoverUDPMsg(NetMsg* netmsg, appladdress* addr, message::qaddr_t source= qaddr_unknown) : | 
|---|
| 195 | message(type_transport, source), peer_assoc(0), type(send_data), netmsg(netmsg), addr(addr) {} | 
|---|
| 196 |  | 
|---|
| 197 | const AssocData* get_peer_assoc() const { return peer_assoc; } | 
|---|
| 198 | TPoverUDPMsg::msg_t get_msgtype() const { return type; } | 
|---|
| 199 | NetMsg* get_netmsg() const { return netmsg; } | 
|---|
| 200 | appladdress* get_appladdr() const { return addr; } | 
|---|
| 201 | }; | 
|---|
| 202 |  | 
|---|
| 203 | } // end namespace protlib | 
|---|
| 204 |  | 
|---|
| 205 | #endif | 
|---|