UDPTunnel.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 
00018 #include <oasys/io/NetUtils.h>
00019 
00020 #include "DTNTunnel.h"
00021 #include "UDPTunnel.h"
00022 
00023 namespace dtntunnel {
00024 
00025 //----------------------------------------------------------------------
00026 UDPTunnel::UDPTunnel()
00027     : IPTunnel("UDPTunnel", "/dtntunnel/udp"),
00028       sock_("/dtntunnel/udp/sock")
00029 {
00030     sock_.init_socket();
00031 }
00032 
00033 //----------------------------------------------------------------------
00034 void
00035 UDPTunnel::add_listener(in_addr_t listen_addr, u_int16_t listen_port,
00036                         in_addr_t remote_addr, u_int16_t remote_port)
00037 {
00038     // the object will delete itself when the thread exits
00039     new Listener(listen_addr, listen_port, remote_addr, remote_port);
00040 }
00041     
00042 //----------------------------------------------------------------------
00043 void
00044 UDPTunnel::handle_bundle(dtn::APIBundle* bundle)
00045 {
00046     DTNTunnel::BundleHeader hdr;
00047     memcpy(&hdr, bundle->payload_.buf(), sizeof(hdr));
00048     hdr.remote_port_ = htons(hdr.remote_port_);
00049 
00050     char* bp = bundle->payload_.buf() + sizeof(hdr);
00051     int  len = bundle->payload_.len() - sizeof(hdr);
00052     
00053     int cc = sock_.sendto(bp, len,
00054                            0, hdr.remote_addr_, hdr.remote_port_);
00055     if (cc != len) {
00056         log_err("error sending packet to %s:%d: %s",
00057                 intoa(hdr.remote_addr_), hdr.remote_port_, strerror(errno));
00058     } else {
00059         log_info("sent %zu byte packet to %s:%d",
00060                  bundle->payload_.len() - sizeof(hdr),
00061                  intoa(hdr.remote_addr_), hdr.remote_port_);
00062     }
00063 
00064     delete bundle;
00065 }
00066 
00067 //----------------------------------------------------------------------
00068 UDPTunnel::Listener::Listener(in_addr_t listen_addr, u_int16_t listen_port,
00069                               in_addr_t remote_addr, u_int16_t remote_port)
00070     : Thread("UDPTunnel::Listener", DELETE_ON_EXIT),
00071       Logger("UDPTunnel::Listener", "/dtntunnel/udp/listener"), 
00072       sock_("/dtntunnel/udp/listener/sock"),
00073       listen_addr_(listen_addr),
00074       listen_port_(listen_port),
00075       remote_addr_(remote_addr),
00076       remote_port_(remote_port)
00077 {
00078     start();
00079 }
00080 
00081 //----------------------------------------------------------------------
00082 void
00083 UDPTunnel::Listener::run()
00084 {
00085     DTNTunnel* tunnel = DTNTunnel::instance();
00086     int ret = sock_.bind(listen_addr_, listen_port_);
00087     if (ret != 0) {
00088         log_err("can't bind to %s:%u", intoa(listen_addr_), listen_port_);
00089         return; // die
00090     }
00091 
00092     DTNTunnel::BundleHeader hdr;
00093     hdr.protocol_    = IPPROTO_UDP;
00094     hdr.seqno_       = 0;
00095     hdr.client_addr_ = listen_addr_;
00096     hdr.client_port_ = htons(listen_port_);
00097     hdr.remote_addr_ = remote_addr_;
00098     hdr.remote_port_ = htons(remote_port_);
00099     
00100     while (1) {
00101         int len = sock_.recv(recv_buf_, sizeof(recv_buf_), 0);
00102         if (len <= 0) {
00103             log_err("error reading from socket: %s", strerror(errno));
00104             return; // die
00105         }
00106         
00107         log_info("got %d byte packet", len);
00108 
00109         dtn::APIBundle* b = new dtn::APIBundle();
00110         char* bp = b->payload_.buf(sizeof(hdr) + len);
00111         memcpy(bp, &hdr, sizeof(hdr));
00112         memcpy(bp + sizeof(hdr), recv_buf_, len);
00113         b->payload_.set_len(sizeof(hdr) + len);
00114         
00115         if (tunnel->send_bundle(b, tunnel->dest_eid()) != DTN_SUCCESS)
00116             exit(1);
00117     }
00118 }
00119 
00120 } // namespace dtntunnel

Generated on Thu Jun 7 12:54:30 2007 for DTN Reference Implementation by  doxygen 1.5.1