Exemplo n.º 1
0
 void OnReceived(_UInt32 nbytes, StreamBuffer::Node* node, const error_code& error)
 {
     m_PendingRecvRequestCount--;
     node->m_Len = nbytes;
     m_Wrapper->m_IStream.PushNode(node);
     if (error.value() != 0)
     {
         if (m_PendingRecvRequestCount == 0 && m_RequestSendRequestCount == 0)
         {
             if (!(error.value() == 104 || error.value() == 54))
             {
                 m_Wrapper->Close();
             }
             if (!m_Wrapper->m_OnConnectBroken.Empty())
             {
                 m_Wrapper->m_OnConnectBroken(m_Wrapper, m_Wrapper->m_IStream, m_Wrapper->m_OStream);
             }
         }
     }
     else
     {
         AsyncReceive();
         m_Wrapper->m_OnReceived(m_Wrapper, m_Wrapper->m_IStream, m_Wrapper->m_OStream);
     }
 }
Exemplo n.º 2
0
bool
SkyLinesTracking::Client::Open(boost::asio::ip::udp::endpoint _endpoint)
{
    Close();

    endpoint = _endpoint;

    boost::system::error_code ec;
    socket.open(endpoint.protocol(), ec);
    if (ec)
        return false;

    if (handler != nullptr) {
        AsyncReceive();
        handler->OnSkyLinesReady();
    }

    return true;
}
Exemplo n.º 3
0
void
Server::OnReceive(const boost::system::error_code &ec, size_t size)
{
  // TODO: use recvmmsg() on Linux

  if (ec) {
    if (ec == boost::asio::error::operation_aborted)
      return;

    socket.close();

    OnError(boost::system::system_error(ec));
    return;
  }

  OnDatagramReceived(std::move(client_buffer), buffer, size);

  AsyncReceive();
}
Exemplo n.º 4
0
 void OnConnected(const std::string& remote, _UInt16 port, const error_code& error)
 {
     if (error.value() == 0)
     {
         m_Wrapper->m_IStream.Clear();  // Hack by hailong for re-connection
         m_Wrapper->m_OStream.Clear();  
         CloseLinger();
         AsyncReceive();
         m_Wrapper->m_OnConnected(m_Wrapper, m_Wrapper->m_IStream, m_Wrapper->m_OStream);
     }
     else 
     {
         m_Wrapper->m_Errno = IGAME_ERROR_CONNECT;
         m_Socket.close();
         if (!m_Wrapper->m_OnConnectFailed.Empty())
         {
             m_Wrapper->m_OnConnectFailed(m_Wrapper, m_Wrapper->m_IStream, m_Wrapper->m_OStream);
         }
     }
 }
Exemplo n.º 5
0
 void AddressBookSubscription::Request ()
 {
     // must be run in separate thread   
     LogPrint (eLogInfo, "Downloading hosts from ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
     bool success = false;   
     i2p::util::http::url u (m_Link);
     i2p::data::IdentHash ident;
     if (m_Book.GetIdentHash (u.host_, ident))
     {
         std::condition_variable newDataReceived;
         std::mutex newDataReceivedMutex;
         auto leaseSet = m_Book.getSharedLocalDestination()->FindLeaseSet (ident);
         if (!leaseSet)
         {
             std::unique_lock<std::mutex> l(newDataReceivedMutex);
             m_Book.getSharedLocalDestination()->RequestDestination (ident,
                 [&newDataReceived, &leaseSet](std::shared_ptr<i2p::data::LeaseSet> ls)
                 {
                     leaseSet = ls;
                     newDataReceived.notify_all ();
                 });
             if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout)
                 LogPrint (eLogError, "Subscription LeseseSet request timeout expired");
         }
         if (leaseSet)
         {
             std::stringstream request, response;
             // standard header
             request << "GET " << u.path_ << " HTTP/1.1\r\nHost: " << u.host_
             << "\r\nAccept: */*\r\n" << "User-Agent: Wget/1.11.4\r\n" << "Connection: close\r\n";
             if (m_Etag.length () > 0) // etag
                 request << i2p::util::http::IF_NONE_MATCH << ": \"" << m_Etag << "\"\r\n";
             if (m_LastModified.length () > 0) // if-modfief-since
                 request << i2p::util::http::IF_MODIFIED_SINCE << ": " << m_LastModified << "\r\n";
             request << "\r\n"; // end of header
             auto stream = m_Book.getSharedLocalDestination()->CreateStream (leaseSet, u.port_);
             stream->Send ((uint8_t *)request.str ().c_str (), request.str ().length ());
             
             uint8_t buf[4096];
             bool end = false;
             while (!end)
             {
                 stream->AsyncReceive (boost::asio::buffer (buf, 4096), 
                     [&](const boost::system::error_code& ecode, std::size_t bytes_transferred)
                     {
                         if (bytes_transferred)
                             response.write ((char *)buf, bytes_transferred);
                         if (ecode == boost::asio::error::timed_out || !stream->IsOpen ())
                             end = true; 
                         newDataReceived.notify_all ();
                     },
                     30); // wait for 30 seconds
                 std::unique_lock<std::mutex> l(newDataReceivedMutex);
                 if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout)
                     LogPrint (eLogError, "Subscription timeout expired");
             }
             // process remaining buffer
             while (size_t len = stream->ReadSome (buf, 4096))
                 response.write ((char *)buf, len);
             
             // parse response
             std::string version;
             response >> version; // HTTP version
             int status = 0;
             response >> status; // status
             if (status == 200) // OK
             {
                 bool isChunked = false;
                 std::string header, statusMessage;
                 std::getline (response, statusMessage);
                 // read until new line meaning end of header
                 while (!response.eof () && header != "\r")
                 {
                     std::getline (response, header);
                     auto colon = header.find (':');
                     if (colon != std::string::npos)
                     {
                         std::string field = header.substr (0, colon);
                         header.resize (header.length () - 1); // delete \r  
                         if (field == i2p::util::http::ETAG)
                             m_Etag = header.substr (colon + 1);
                         else if (field == i2p::util::http::LAST_MODIFIED)
                             m_LastModified = header.substr (colon + 1);
                         else if (field == i2p::util::http::TRANSFER_ENCODING)
                             isChunked = !header.compare (colon + 1, std::string::npos, "chunked");
                     }   
                 }
                 LogPrint (eLogInfo, m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
                 if (!response.eof ())   
                 {
                     success = true;
                     if (!isChunked)
                         m_Book.LoadHostsFromStream (response);
                     else
                     {
                         // merge chunks
                         std::stringstream merged;
                         i2p::util::http::MergeChunkedResponse (response, merged);
                         m_Book.LoadHostsFromStream (merged);
                     }   
                 }   
             }
             else if (status == 304)
             {   
                 success = true;
                 LogPrint (eLogInfo, "No updates from ", m_Link);
             }   
             else
                 LogPrint (eLogWarning, "Adressbook HTTP response ", status);
         }
         else
Exemplo n.º 6
0
Server::Server(boost::asio::io_service &io_service,
               boost::asio::ip::udp::endpoint endpoint)
  :socket(io_service, endpoint)
{
  AsyncReceive();
}