00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <oasys/io/NetUtils.h>
00040
00041 #include "DTNTunnel.h"
00042 #include "UDPTunnel.h"
00043
00044 namespace dtntunnel {
00045
00046
00047 UDPTunnel::UDPTunnel()
00048 : IPTunnel("UDPTunnel", "/dtntunnel/udp"),
00049 sock_("/dtntunnel/udp/sock")
00050 {
00051 sock_.init_socket();
00052 }
00053
00054
00055 void
00056 UDPTunnel::add_listener(in_addr_t listen_addr, u_int16_t listen_port,
00057 in_addr_t remote_addr, u_int16_t remote_port)
00058 {
00059
00060 new Listener(listen_addr, listen_port, remote_addr, remote_port);
00061 }
00062
00063
00064 void
00065 UDPTunnel::handle_bundle(dtn::APIBundle* bundle)
00066 {
00067 DTNTunnel::BundleHeader hdr;
00068 memcpy(&hdr, bundle->payload_.buf(), sizeof(hdr));
00069 hdr.remote_port_ = htons(hdr.remote_port_);
00070
00071 char* bp = bundle->payload_.buf() + sizeof(hdr);
00072 int len = bundle->payload_.len() - sizeof(hdr);
00073
00074 int cc = sock_.sendto(bp, len,
00075 0, hdr.remote_addr_, hdr.remote_port_);
00076 if (cc != len) {
00077 log_err("error sending packet to %s:%d: %s",
00078 intoa(hdr.remote_addr_), hdr.remote_port_, strerror(errno));
00079 } else {
00080 log_info("sent %zu byte packet to %s:%d",
00081 bundle->payload_.len() - sizeof(hdr),
00082 intoa(hdr.remote_addr_), hdr.remote_port_);
00083 }
00084
00085 delete bundle;
00086 }
00087
00088
00089 UDPTunnel::Listener::Listener(in_addr_t listen_addr, u_int16_t listen_port,
00090 in_addr_t remote_addr, u_int16_t remote_port)
00091 : Thread("UDPTunnel::Listener", DELETE_ON_EXIT),
00092 Logger("UDPTunnel::Listener", "/dtntunnel/udp/listener"),
00093 sock_("/dtntunnel/udp/listener/sock"),
00094 listen_addr_(listen_addr),
00095 listen_port_(listen_port),
00096 remote_addr_(remote_addr),
00097 remote_port_(remote_port)
00098 {
00099 start();
00100 }
00101
00102
00103 void
00104 UDPTunnel::Listener::run()
00105 {
00106 DTNTunnel* tunnel = DTNTunnel::instance();
00107 int ret = sock_.bind(listen_addr_, listen_port_);
00108 if (ret != 0) {
00109 log_err("can't bind to %s:%u", intoa(listen_addr_), listen_port_);
00110 return;
00111 }
00112
00113 DTNTunnel::BundleHeader hdr;
00114 hdr.protocol_ = IPPROTO_UDP;
00115 hdr.seqno_ = 0;
00116 hdr.client_addr_ = listen_addr_;
00117 hdr.client_port_ = htons(listen_port_);
00118 hdr.remote_addr_ = remote_addr_;
00119 hdr.remote_port_ = htons(remote_port_);
00120
00121 while (1) {
00122 int len = sock_.recv(recv_buf_, sizeof(recv_buf_), 0);
00123 if (len <= 0) {
00124 log_err("error reading from socket: %s", strerror(errno));
00125 return;
00126 }
00127
00128 log_info("got %d byte packet", len);
00129
00130 dtn::APIBundle* b = new dtn::APIBundle();
00131 char* bp = b->payload_.buf(sizeof(hdr) + len);
00132 memcpy(bp, &hdr, sizeof(hdr));
00133 memcpy(bp + sizeof(hdr), recv_buf_, len);
00134 b->payload_.set_len(sizeof(hdr) + len);
00135
00136 if (tunnel->send_bundle(b, tunnel->dest_eid()) != DTN_SUCCESS)
00137 exit(1);
00138 }
00139 }
00140
00141 }