source: sample/AribaTunnel/Tunnel.cpp

Last change on this file was 12457, checked in by hock@…, 11 years ago

added AribaTunnel to the repo

File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2013 Mario Hock mails2013@omnifile.org
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27#include "Tunnel.h"
28
29#include <ariba/utility/system/SystemQueue.h>
30
31#include <iostream>
32#include <boost/property_tree/ptree.hpp>
33
34
35using namespace std;
36using ariba::utility::SystemQueue;
37
38const ariba::ServiceID Tunnel::TUNNEL_SERVICE_ID(99);
39
40
41Tunnel::Tunnel() :
42 udp_sender(NULL)
43{
44}
45
46Tunnel::~Tunnel()
47{
48
49}
50
51void Tunnel::init_ariba(ptree config)
52{
53 string my_name;
54 string remote_name;
55
56 logging_info( "[TUNNEL]\t starting up Tunnel service ... " );
57
58 // use node name also in the application
59 my_name = config.get("ariba.node_name", "NO_NAME");
60
61 // bind communication and node listener
62 node.bind( this ); /*NodeListener*/
63 node.bind( this, TUNNEL_SERVICE_ID); /*CommunicationListener*/
64
65 // connecting
66 logging_debug( "connecting ... " );
67
68 node.connect(config.get_child("ariba"));
69
70 logging_info( "[TUNNEL]\t ariba-tunnel starting up with"
71 << " [spovnetid " << node.getSpoVNetId().toString() << "]"
72 << " and [nodeid " << node.getNodeId().toString() << "]" );
73
74
75 // get the other tunnel endpoint from config
76 try
77 {
78 remote_name = config.get<string>("tunnel.connect_to_node");
79
80 tunnel_endpoint = ariba::Name(remote_name).toNodeId();
81
82 logging_info( "[TUNNEL]\t I am »" << my_name << "« and I'll try to connect to: »" << remote_name << "«");
83 }
84 catch ( boost::property_tree::ptree_bad_path& e )
85 {
86 logging_warn( "[TUNNEL]\t I am »" << my_name << "« but I don't know the other tunnel endpoint!");
87 }
88}
89
90
91
92/* communication listener interface */
93void Tunnel::onMessage(reboost::shared_buffer_t message,
94 const NodeID& remote,
95 const LinkID& lnk,
96 const SequenceNumber& seqnum,
97 const ariba::overlay::OverlayMsg* overlay_msg)
98{
99 logging_info( "[ARIBA] received " << message.size() << " bytes from node: " << remote.toString() );
100
101 /// forward ariba message over UDP
102 if ( udp_sender != NULL )
103 {
104 udp_sender->SendMessage(message);
105 }
106 else
107 {
108 logging_warn("/// NO UDP SENDER REGISTERED");
109 }
110}
111
112void Tunnel::onLinkUp(const LinkID& lnk, const NodeID& remote)
113{
114 logging_info("[TUNNEL]\t LINK UP");
115
116 // TODO Maybe we should decide for one link instead of maintaining several..
117
118 // only accept links to the other tunnel endpoint
119 if ( remote == tunnel_endpoint )
120 {
121 links.push_back(lnk);
122 }
123 else
124 {
125 node.dropLink(lnk);
126 }
127}
128
129void Tunnel::onLinkDown(const LinkID& lnk, const NodeID& remote)
130{
131 std::vector<LinkID>::iterator it = find(links.begin(), links.end(), lnk);
132
133 if ( it != links.end() )
134 links.erase(it);
135}
136
137
138
139/* node listener interface */
140void Tunnel::onOverlayConnected(const SpoVNetID& vid)
141{
142 logging_info( "/// OverlayConnected" );
143
144 // establish link to the other tunnel endpoint
145 node.establishLink(tunnel_endpoint, TUNNEL_SERVICE_ID);
146}
147
148void Tunnel::onOverlayDisconnected(const SpoVNetID& vid)
149{
150 logging_info( "/// OverlayDisconnected" );
151}
152
153
154
155
156/// * to be called from an EXTERNAL THREAD *
157void Tunnel::SendMessage(reboost::message_t msg)
158{
159 /// synchronize with the Ariba Thread
160 SystemQueue::instance().scheduleCall(
161 boost::bind(
162 &Tunnel::send_message,
163 this,
164 msg)
165 );
166}
167void Tunnel::SendMessage(reboost::shared_buffer_t msg)
168{
169 reboost::message_t message;
170 message.push_back(msg);
171
172 this->SendMessage(message);
173}
174
175
176
177/// * to be called within the ARIBA THREAD *
178void Tunnel::send_message(reboost::message_t msg)
179{
180 if ( ! links.empty() )
181 {
182 logging_info( "[ARIBA] sending " << msg.size() << " bytes over link: " << links[0].toString() );
183
184 node.sendMessage(msg, links[0]);
185 }
186 else
187 {
188 logging_warn( "[ARIBA] would like to send " << msg.size() << " bytes. But there is no active link!" );
189 }
190}
191
192
193void Tunnel::register_udp_sender(MessageSenderInterface* udp_sender)
194{
195 this->udp_sender = udp_sender;
196}
197
198
199
200
201// /// XXX this is only for debug output
202// void Tunnel::print_message(const string& prefix, reboost::message_t msg)
203// {
204// // XXX testing (debug output)
205// reboost::shared_buffer_t buf = msg.linearize();
206// print_message(prefix, buf);
207// }
208// void Tunnel::print_message(const string& prefix, reboost::shared_buffer_t buf)
209// {
210// string s((const char*) buf.data(), buf.size() - 1);
211// std::cout << prefix << "»" << s << "«" << std::endl;
212// }
213
Note: See TracBrowser for help on using the repository browser.