void chat_server_handler::on_message(connection_ptr con, message_ptr msg) { if (msg->get_opcode() != websocketpp::frame::opcode::text) { return; } std::cout << "message from client " << con << ": " << msg->get_payload() << std::endl; // check for special command messages if (msg->get_payload() == "/help") { // print command list con->send(encode_message("server","avaliable commands:<br /> /help - show this help<br /> /alias foo - set alias to foo",false)); return; } if (msg->get_payload().substr(0,7) == "/alias ") { std::string response; std::string alias; if (msg->get_payload().size() == 7) { response = "you must enter an alias."; con->send(encode_message("server",response)); return; } else { alias = msg->get_payload().substr(7); } response = m_connections[con] + " is now known as "+alias; // store alias pre-escaped so we don't have to do this replacing every time this // user sends a message // escape json characters boost::algorithm::replace_all(alias,"\\","\\\\"); boost::algorithm::replace_all(alias,"\"","\\\""); // escape html characters boost::algorithm::replace_all(alias,"&","&"); boost::algorithm::replace_all(alias,"<","<"); boost::algorithm::replace_all(alias,">",">"); m_connections[con] = alias; // set alias send_to_all(serialize_state()); send_to_all(encode_message("server",response)); return; } // catch other slash commands if ((msg->get_payload())[0] == '/') { con->send(encode_message("server","unrecognized command")); return; } // create json message to send based on msg send_to_all(encode_message(m_connections[con],msg->get_payload())); }
void send_messages( connection_ptr connection ) { // Check if sending has been completed.... if (connection->send()) { error_code ec; util::unique_function_nonser< void( error_code const& , parcelset::locality const& , connection_ptr ) > postprocess_handler; std::swap(postprocess_handler, connection->postprocess_handler_); postprocess_handler( ec, connection->destination(), connection); } else { std::unique_lock<mutex_type> l(connections_mtx_); connections_.push_back(std::move(connection)); } }
void handle_get_trx_block( const connection_ptr& c, chan_data& cdat, get_trx_block_message msg ) { try { // TODO: throttle attempts to query blocks by a single connection uint32_t blk_num = _db->fetch_block_num( msg.block_id ); trx_block blk = _db->fetch_trx_block( blk_num ); c->send( network::message(trx_block_message( blk ), _chan_id ) ); } FC_RETHROW_EXCEPTIONS( warn, "", ("msg",msg) ) } // provide stack trace for errors
/* ===================================================== */ void handle_get_name_inv( const connection_ptr& con, chan_data& cdat, const get_name_inv_message& msg ) { name_inv_message reply; reply.name_trxs = _trx_broadcast_mgr.get_inventory( cdat.trxs_mgr ); cdat.trxs_mgr.update_known( reply.name_trxs ); con->send( network::message(reply,_chan_id) ); }
void on_message(connection_ptr con, message_ptr msg) { if (con->get_resource() == "/getcasecount") { std::cout << "detected " << msg->get_payload() << " test cases." << std::endl; m_case_count = atoi(msg->get_payload().c_str()); } else { con->send(msg->get_payload(),msg->get_opcode()); } }
void chat_server_handler::on_open(connection_ptr con) { std::cout << "client " << con << " joined the lobby." << std::endl; m_connections.insert(std::pair<connection_ptr,std::string>(con,get_con_id(con))); // send user list and signon message to all clients send_to_all(serialize_state()); con->send(encode_message("server","welcome, use the /alias command to set a name, /help for a list of other commands.")); send_to_all(encode_message("server",m_connections[con]+" has joined the chat.")); }
void on_open(connection_ptr con) { // now it is safe to use the connection std::cout << "connection ready" << std::endl; received = false; std::string SIP_msg="OPTIONS sip:[email protected] SIP/2.0\r\nVia: SIP/2.0/WS df7jal23ls0d.invalid;rport;branch=z9hG4bKhjhs8ass877\r\nMax-Forwards: 70\r\nTo: <sip:[email protected]>\r\nFrom: Alice <sip:[email protected]>;tag=1928301774\r\nCall-ID: a84b4c76e66710\r\nCSeq: 63104 OPTIONS\r\nContact: <sip:[email protected]>\r\nAccept: application/sdp\r\nContent-Length: 0\r\n\r\n"; con->send(SIP_msg.c_str()); }
bool ConnectService::process(message_ptr const & message, connection_ptr const & connection) { static Engine& engine = Engine::get_instance(); if (message->type != MessageType::PING) return false; uint32_t id; _dec_declare2_(req, message->get_content_data(), message->get_content_size()); _dec_get_var32_(req, id); if (!_dec_valid_(req)) { DLOG(ERROR) << "Bad Ping format"; return true; } NodeConf* config = (NodeConf*) engine.get_component(COMP_SERVERCONF).get(); servernode_map::iterator it = config->nodes.find(id); if (it != config->nodes.end()) { servernode_ptr node = it->second; connection->asyn = true; connection->authenticated = true; connection->data = node.get(); connection->type = CT_S2S; node->connection = connection; node->state = READY; _enc_declare_(rep, 64); _enc_put_msg_header_(rep, MessageType::REPLY, message->id, 0); _enc_put_var32_(rep, ErrorCode::OK); _enc_update_msg_size_(rep); connection->send(_enc_data_(rep), _enc_size_(rep)); } else { _enc_declare_(rep, 64); _enc_put_msg_header_(rep, MessageType::REPLY, message->id, 0); _enc_put_var32_(rep, ErrorCode::IS_NOT_FOUND); _enc_update_msg_size_(rep); connection->send(_enc_data_(rep), _enc_size_(rep)); } return true; }
/* ===================================================== */ void handle_get_block_index( const connection_ptr& con, chan_data& cdat, const get_block_index_message& msg ) { try { ilog( "${msg}", ("msg",msg) ); const fc::optional<name_block_index>& trx = _block_index_broadcast_mgr.get_value( msg.block_id ); if( !trx ) // must be a db { auto debug_str = _block_index_broadcast_mgr.debug(); FC_ASSERT( !"Name block index not in broadcast cache", "${str}", ("str",debug_str) ); } con->send( network::message( block_index_message( *trx ), _chan_id ) ); } FC_RETHROW_EXCEPTIONS( warn, "", ("msg",msg) ) }
void handle_get_full_block( const connection_ptr& c, chan_data& cdat, get_full_block_message msg ) { try { // TODO: throttle attempts to query blocks by a single connection // this request must hit the DB... cost in proof of work is proportional to age to prevent // cache thrashing attacks and allowing us to keep newer blocks in the cache // penalize connections that request too many full blocks... uint32_t blk_num = _db->fetch_block_num( msg.block_id ); full_block blk = _db->fetch_full_block( blk_num ); c->send( network::message(full_block_message( blk ), _chan_id ) ); } FC_RETHROW_EXCEPTIONS( warn, "", ("msg",msg) ) } // provide stack trace for errors
void on_message(connection_ptr con,message_ptr msg) { int value = atoi(msg->get_payload().c_str()); if (value == 0) { con->send("Invalid sleep value."); } else { request r; r.con = con; r.value = value; r.process(); } }
void on_message(connection_ptr con,message_ptr msg) { int value = atoi(msg->get_payload().c_str()); if (value == 0) { con->send("invalid sleep value."); } else { request r; r.con = con; r.value = value; m_coordinator.add_request(r); } }
void on_open(connection_ptr con) { std::stringstream o; o << "{" << "\"type\":\"test_welcome\"," << "\"version\":\"" << m_ua << "\"," << "\"ident\":\"" << m_ident << "\"," << "\"num_workers\":" << m_num_workers << "}"; con->send(o.str()); }
void handle_get_trx_inv( const connection_ptr& c, chan_data& cdat, get_trx_inv_message msg ) { try { // TODO: only allow this request once every couple of minutes to prevent flood attacks // TODO: make sure these inventory items are sorted by fees trx_inv_message reply; reply.items.reserve( TRX_INV_QUERY_LIMIT ); for( auto itr = _pending_trx.begin(); reply.items.size() < TRX_INV_QUERY_LIMIT && itr != _pending_trx.end(); ++itr ) { reply.items.push_back( itr->first ); } c->send( network::message( reply, _chan_id ) ); } FC_RETHROW_EXCEPTIONS( warn, "", ("msg",msg) ) } // provide stack trace for errors
void handle_get_priv( const connection_ptr& c, bitchat_chan_data& cd, const get_priv_message& msg ) { // TODO: throttle the rate at which get_priv may be called for a given connection for( auto itr = msg.items.begin(); itr != msg.items.end(); ++itr ) { auto m = priv_msgs.find( *itr ); if( m != priv_msgs.end() ) { c->send( network::message( m->second, chan_id ) ); cd.known_inv.insert( *itr ); } } }
/** * Send all inventory items that are not known to c and are dated 'after' */ void handle_get_inv( const connection_ptr& c, bitchat_chan_data& cd, const get_inv_message& msg ) { inv_message reply; for( auto itr = msg_time_index.lower_bound( fc::time_point(msg.after) ); itr != msg_time_index.end(); ++itr ) { if( cd.known_inv.insert( itr->second ).second ) { reply.items.push_back( itr->second ); cd.known_inv.insert( itr->second ); } } c->send( network::message( reply, chan_id ) ); }
/* ===================================================== * When a new node connects it must locate the best block chain that extends the * current known chain. **/ void request_block_headers( const connection_ptr& con ) { try { ilog( "requesting block headers from ${ep}", ("ep",con->remote_endpoint() )); chan_data& cdat = get_channel_data(con); if( cdat.requested_headers ) return; get_headers_message request; const std::vector<name_id_type>& ids = _name_db.get_header_ids(); uint32_t delta = 1; for( int32_t i = ids.size() - 1; i >= 0; ) { request.locator_hashes.push_back(ids[i]); i -= delta; delta *= 2; } cdat.requested_headers = fc::time_point::now(); con->send( network::message(request,_chan_id) ); } FC_RETHROW_EXCEPTIONS( warn, "") }
void send_stats_update(connection_ptr connection) { if (m_msg_stats.empty()) { return; } // example: `ack:e3458d0aceff8b70a3e5c0afec632881=38;e3458d0aceff8b70a3e5c0afec632881=42;` std::stringstream msg; msg << "ack:"; std::map<std::string,size_t>::iterator it; for (it = m_msg_stats.begin(); it != m_msg_stats.end(); it++) { msg << (*it).first << "=" << (*it).second << ";"; } std::cout << "sending " << msg.str() << std::endl; connection->send(msg.str()); m_msg_stats.clear(); }
/* ===================================================== */ void handle_get_name( const connection_ptr& con, chan_data& cdat, const get_name_header_message& msg ) { ilog( "${msg}", ("msg",msg) ); const fc::optional<name_header>& trx = _trx_broadcast_mgr.get_value( msg.name_trx_id ); if( !trx ) // must be a db { auto debug_str = _trx_broadcast_mgr.debug(); FC_ASSERT( !"Name transaction not in broadcast cache", "${str}", ("str",debug_str) ); /* ... we should not allow fetching of individual name trx from our db... this would require a huge index name_header trx = _name_db.fetch_trx_header( msg.name_trx_id ); con->send( network::message( name_header_message( trx ), _chan_id ) ); */ } else { con->send( network::message( name_header_message( *trx ), _chan_id ) ); } }
void on_message(connection_ptr con, message_ptr msg) { if(msg->get_payload()=="skeleton") { con->send(getImageData(),msg->get_opcode()); } else if(msg->get_payload()=="depth") { con->send(getDepthMap(true),msg->get_opcode()); } else if(msg->get_payload()=="rgb") { con->send(getRGBImage(true),msg->get_opcode()); } else if(msg->get_payload()=="savergb") { con->send(saveRGBImage(),msg->get_opcode()); } else if(msg->get_payload()=="savedepth") { con->send(saveDepthMap(),msg->get_opcode()); } else { con->send("Unknown client request",msg->get_opcode()); } }
/** * Received in response to get_headers message, we should certify that we requested this. */ void handle_headers( const connection_ptr& con, chan_data& cdat, const headers_message& msg ) { try { FC_ASSERT( !!cdat.requested_headers ); cdat.requested_headers.reset(); // TODO: validate that all ids reported have the min proof of work for a name. ilog( "received ${x} block headers", ("msg",msg.headers.size() ) ); _fork_db.cache_header( msg.first ); _new_block_info = true; name_id_type prev_id = msg.first.id(); for( auto itr = msg.headers.begin(); itr != msg.headers.end(); ++itr ) { name_header next_head( *itr, prev_id ); ilog( "${id} = ${next_head}", ("id",next_head.id())("next_head",next_head) ); _fork_db.cache_header( next_head ); prev_id = next_head.id(); if( prev_id > max_name_hash() ) { // then we should disconnect.... wlog( "node produced name header with insufficient minimum work" ); con->close(); return; } cdat.available_blocks.insert(prev_id); } if( prev_id != msg.head_block_id ) { cdat.requested_headers = fc::time_point::now(); get_headers_message request; request.locator_hashes.push_back( prev_id ); con->send( network::message( request, _chan_id ) ); } } FC_RETHROW_EXCEPTIONS( warn, "", ("msg",msg) ) }
void handle_get_trxs( const connection_ptr& c, chan_data& cdat, get_trxs_message msg ) { try { trxs_message reply; FC_ASSERT( msg.items.size() < TRX_INV_QUERY_LIMIT ); reply.trxs.reserve( msg.items.size() ); for( auto itr = msg.items.begin(); itr != msg.items.end(); ++itr ) { auto pending_itr = _pending_trx.find( *itr ); if( pending_itr == _pending_trx.end() ) { // TODO DB queries are far more expensive, and therefore must be rationed and potentialy // require a proof of work paying us to fetch them auto tx_num = _db->fetch_trx_num( *itr ); reply.trxs.push_back( _db->fetch_trx(tx_num) ); } else { reply.trxs.push_back( pending_itr->second ); } } c->send( network::message( reply, _chan_id ) ); } FC_RETHROW_EXCEPTIONS( warn, "", ("msg",msg) ) } // provide stack trace for errors
/* ===================================================== */ void handle_get_headers( const connection_ptr& con, chan_data& cdat, const get_headers_message& msg ) { try { // TODO: prevent abuse of this message... only allow it at a limited rate and take notice // when the remote node starts abusing it. uint32_t start_block = 0; for( uint32_t i = 0; i < msg.locator_hashes.size(); ++i ) { try { start_block = _name_db.get_block_num( msg.locator_hashes[i] ); break; } catch ( const fc::exception& e ) { // TODO: should I do something other than log this exception? wlog( "apparently this node is on a different fork, error fetching ${id}\n${e}", ("id", msg.locator_hashes[i] )("e",e.to_detail_string()) ); } } const std::vector<name_id_type>& ids = _name_db.get_header_ids(); uint32_t end = std::min<uint32_t>(start_block+2000, ids.size() ); headers_message reply; reply.first_block_num = start_block; reply.first = _name_db.fetch_block_header(start_block); reply.headers.reserve( end - start_block - 1 ); for( auto i = start_block+1; i < end; ++i ) { reply.headers.push_back( _name_db.fetch_block_header(ids[i]) ); } reply.head_block_num = ids.size() - 1; reply.head_block_id = ids.back(); con->send( network::message( reply, _chan_id ) ); } FC_RETHROW_EXCEPTIONS( warn, "", ("msg",msg) ) }
void command_error(connection_ptr connection,const std::string msg) { connection->send("{\"type\":\"error\",\"value\":\""+msg+"\"}"); }
BOOST_FOREACH(connection_ptr conn, m_connections) { conn->send(data); }
void on_message(connection_ptr con,message_ptr msg) { con->send(msg->get_payload(),msg->get_opcode()); }
void Handler::on_open(connection_ptr con) { Log::debug("client <%s>: joined", plain(con).c_str()); m_connections.insert(con); con->send(format_message("hello")); }
/* ===================================================== */ void handle_get_block( const connection_ptr& con, chan_data& cdat, const get_block_message& msg ) { try { // TODO: charge POW for this... auto block = _name_db.fetch_block( msg.block_id ); con->send( network::message( block_message( std::move(block) ), _chan_id ) ); } FC_RETHROW_EXCEPTIONS( warn, "", ("msg",msg) ) }