Permalink
Browse files

*internal API change* for config get_json, allow lan plugin to specif…

…y a list of udp endpoints
  • Loading branch information...
1 parent 24625f3 commit fd85cbb3e169ae64533d751d69905281ad8810db @RJ committed Jul 11, 2009
View
@@ -7,11 +7,6 @@
"load_scripts" : true,
"plugins" : {
- "lan" :
- {
- "port" : 8888,
- "multicast" : "239.255.0.1"
- },
"boffin" :
{
"db" : "boffin.db"
@@ -67,6 +67,8 @@ class Config
template <typename T>
T get(std::string k, T def) const;
+
+
// NOT WORKING YET
template <typename T>
bool set(std::string k, T def);
@@ -97,6 +99,33 @@ class Config
std::string filename()
{ return m_filename; }
+
+ /// gets json Value for a given key
+ json_spirit::Value get_json(std::string k) const
+ {
+ json_spirit::Value def;
+
+ std::vector<std::string> toks;
+ boost::split(toks, k, boost::is_any_of("."));
+ json_spirit::Value val = m_mainval;
+ std::map<std::string, json_spirit::Value> mp;
+ unsigned int i = 0;
+ //cout << "getting: " << k << " size: " << toks.size() << endl;
+ do
+ {
+ if(val.type() != json_spirit::obj_type) return def;
+ json_spirit::obj_to_map(val.get_obj(), mp);
+ if( mp.find(toks[i]) == mp.end() )
+ {
+ //cerr << "1 Can't find " << toks[i] << endl;
+ return def;
+ }
+ //cout << "Got " << toks[i] << endl;
+ val = mp[toks[i]];
+ }
+ while(++i < toks.size());
+ return val;
+ }
private:
@@ -133,6 +162,9 @@ T Config::get(std::string k, T def) const
return val.get_value<T>();
}
+
+
+
template <typename T>
bool Config::set(std::string k, T def)
{
@@ -48,7 +48,7 @@ class PluginAdaptor
template <typename T>
inline T get(const std::string& key, const T& def) const;
-
+ virtual json_spirit::Value get_json(const std::string& key) const = 0;
// results are a vector of json result objects
virtual bool report_results(const query_uid& qid, const std::vector< json_spirit::Object >&) = 0;
@@ -72,6 +72,11 @@ class PluginAdaptorImpl : public PluginAdaptor
return m_config->name();
}
+ virtual json_spirit::Value get_json(const std::string& key) const
+ {
+ return m_config->get_json(key);
+ }
+
virtual json_spirit::Value getstring(const std::string& key, const std::string& def) const
{
// TODO
View
@@ -24,6 +24,9 @@
#include <ctime>
+/// port used for binding the udp endpoints only (nothing to do with tcp/http):
+#define DEFAULT_LAN_PORT 8888
+
using namespace std;
using namespace json_spirit;
@@ -40,13 +43,12 @@ bool
lan::init(pa_ptr pap)
{
m_pap = pap;
- broadcast_endpoint_ =
- new boost::asio::ip::udp::endpoint
- ( boost::asio::ip::address::from_string
- ("239.255.0.1"),
- 8888 );
- //(pap->get<string> ("plugins.lan.multicast", "")),
- // pap->get("plugins.lan.port", 0) );
+ setup_endpoints();
+ if( m_endpoints.size() == 0 )
+ {
+ cerr << "LAN: Error, no valid endpoints configured" << endl;
+ return false;
+ }
m_responder_thread.reset( new boost::thread(boost::bind(&lan::run, this)) );
return true;
@@ -65,8 +67,62 @@ lan::~lan() throw()
if( socket_ )
delete(socket_);
- if( broadcast_endpoint_ )
- delete(broadcast_endpoint_);
+ //if( broadcast_endpoint_ )
+ // delete(broadcast_endpoint_);
+}
+
+/// decide what udp endpoints queries will be sent to.
+/// if nothing is specified, just use the default multicast
+/// otherwise send to everything in the list from the config file
+void
+lan::setup_endpoints()
+{
+ Value endpoints = m_pap->get_json("plugins.lan.endpoints");
+ if( endpoints == Value::null || endpoints.type() != array_type )
+ {
+ // nothing specified, default is just the multicast address:
+ m_endpoints.push_back(
+ new boost::asio::ip::udp::endpoint
+ ( boost::asio::ip::address::from_string
+ ("239.255.0.1"), DEFAULT_LAN_PORT )
+ );
+ cout << "LAN plugin using default multicast address of 239.255.0.1" << endl;
+ }
+ else // manual config of endpoints:
+ {
+ vector<Value> eps = endpoints.get_array();
+ BOOST_FOREACH( Value v, eps )
+ {
+ unsigned short port = DEFAULT_LAN_PORT;
+ string ip;
+ if( v.type() == str_type )
+ {
+ ip = v.get_str();
+ }
+ else if( v.type() != array_type )
+ {
+ continue;
+ }
+ else
+ {
+ vector<Value> pairv = v.get_array();
+ if( pairv.size() == 0 ) continue;
+ if( pairv[0].type() != str_type ) continue;
+ // set port, if specified in the array:
+ if( pairv.size() > 1 && pairv[1].type() == int_type )
+ port = pairv[1].get_int();
+ ip = pairv[0].get_str();
+ }
+ // add new endpoint to the vector:
+ try
+ {
+ m_endpoints.push_back(
+ new boost::asio::ip::udp::endpoint(
+ boost::asio::ip::address::from_string( ip ), port ) );
+ }catch(...){}
+ }
+ cout << "LAN plugin has " << m_endpoints.size() << " endpoints configured." << endl;
+ }
}
void
@@ -76,7 +132,7 @@ lan::start_resolving(boost::shared_ptr<ResolverQuery> rq)
ostringstream querystr;
write_formatted( rq->get_json(), querystr );
//cout << "Resolving: " << querystr.str() << " through the LAN plugin" << endl;
- async_send(broadcast_endpoint_, querystr.str());
+ async_send(querystr.str());
}
void
@@ -140,9 +196,20 @@ lan::start_listening(boost::asio::io_service& io_service,
}
+/// send to all configured endpoints:
+void
+lan::async_send( const string& message )
+{
+ BOOST_FOREACH( boost::asio::ip::udp::endpoint * ep, m_endpoints )
+ {
+ async_send( ep, message );
+ }
+}
+
+/// send to specific endpoints:
void
lan::async_send(boost::asio::ip::udp::endpoint * remote_endpoint,
- string message)
+ const string& message)
{
if(message.length()>max_length)
{
@@ -360,7 +427,7 @@ lan::send_ping()
jq.push_back( Pair("http_port", 8888/*m_pap->get("http_port", 8888)*/) );
ostringstream os;
write_formatted( jq, os );
- async_send(broadcast_endpoint_, os.str());
+ async_send(os.str());
}
/// pong reply back to specific user
@@ -389,7 +456,7 @@ lan::send_pang()
o.push_back( Pair("from_name", m_pap->hostname()) );
ostringstream os;
write_formatted( o, os );
- async_send(broadcast_endpoint_, os.str());
+ async_send(os.str());
}
void
View
@@ -46,10 +46,10 @@ namespace resolvers {
class lan : public ResolverPlugin<lan>
{
public:
- lan(): socket_( 0 ),
- broadcast_endpoint_( 0 ){}
+ lan(): socket_( 0 ){}
virtual bool init(pa_ptr pap);
+ void setup_endpoints();
void run();
void start_resolving(boost::shared_ptr<ResolverQuery> rq);
@@ -98,12 +98,18 @@ class lan : public ResolverPlugin<lan>
size_t bytes_recvd,
char * scratch );
+ void async_send( const std::string& message );
void async_send( boost::asio::ip::udp::endpoint * remote_endpoint,
- std::string message );
+ const std::string& message );
boost::asio::ip::udp::socket * socket_;
boost::asio::ip::udp::endpoint sender_endpoint_;
- boost::asio::ip::udp::endpoint * broadcast_endpoint_;
+ //boost::asio::ip::udp::endpoint * broadcast_endpoint_;
+
+ // list of UDP endpoints to send queries to
+ // typically this just contains the multicast address
+ std::vector<boost::asio::ip::udp::endpoint*> m_endpoints;
+
enum { max_length = 1024 };
char data_[max_length];

0 comments on commit fd85cbb

Please sign in to comment.