Browse Source

prevent race condition in datagram destination

clean up style a bit
pull/628/head
Jeff Becker 8 years ago
parent
commit
c770bcbf96
No known key found for this signature in database
GPG Key ID: AB950234D6EA286B
  1. 12
      AddressBook.cpp
  2. 20
      Datagram.cpp
  3. 14
      Datagram.h
  4. 9
      Tag.h

12
AddressBook.cpp

@ -543,11 +543,12 @@ namespace client
auto dest = i2p::client::context.GetSharedLocalDestination (); auto dest = i2p::client::context.GetSharedLocalDestination ();
if (dest) if (dest)
{ {
auto datagram = dest->GetDatagramDestination (); auto datagram = dest->GetDatagramDestination ();
if(datagram == nullptr) datagram = dest->CreateDatagramDestination(); if (!datagram)
datagram->SetReceiver (std::bind (&AddressBook::HandleLookupResponse, this, datagram = dest->CreateDatagramDestination ();
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); datagram->SetReceiver (std::bind (&AddressBook::HandleLookupResponse, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5),
ADDRESS_RESPONSE_DATAGRAM_PORT);
} }
} }
@ -557,8 +558,7 @@ namespace client
if (dest) if (dest)
{ {
auto datagram = dest->GetDatagramDestination (); auto datagram = dest->GetDatagramDestination ();
if (datagram) if (datagram) datagram->ResetReceiver (ADDRESS_RESPONSE_DATAGRAM_PORT);
datagram->ResetReceiver ();
} }
} }

20
Datagram.cpp

@ -71,18 +71,26 @@ namespace datagram
if (verified) if (verified)
{ {
auto it = m_ReceiversByPorts.find (toPort); auto r = FindReceiver(toPort);
if (it != m_ReceiversByPorts.end ()) if(r)
it->second (identity, fromPort, toPort, buf + headerLen, len -headerLen); r(identity, fromPort, toPort, buf + headerLen, len -headerLen);
else if (m_Receiver != nullptr)
m_Receiver (identity, fromPort, toPort, buf + headerLen, len -headerLen);
else else
LogPrint (eLogWarning, "Receiver for datagram is not set"); LogPrint (eLogWarning, "DatagramDestination: no receiver for port ", toPort);
} }
else else
LogPrint (eLogWarning, "Datagram signature verification failed"); LogPrint (eLogWarning, "Datagram signature verification failed");
} }
DatagramDestination::Receiver DatagramDestination::FindReceiver(uint16_t port)
{
std::lock_guard<std::mutex> lock(m_ReceiversMutex);
Receiver r = m_Receiver;
auto itr = m_ReceiversByPorts.find(port);
if (itr != m_ReceiversByPorts.end())
r = itr->second;
return r;
}
void DatagramDestination::HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) void DatagramDestination::HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
{ {
// unzip it // unzip it

14
Datagram.h

@ -80,8 +80,8 @@ namespace datagram
void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; }; void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; };
void ResetReceiver () { m_Receiver = nullptr; }; void ResetReceiver () { m_Receiver = nullptr; };
void SetReceiver (const Receiver& receiver, uint16_t port) { m_ReceiversByPorts[port] = receiver; }; void SetReceiver (const Receiver& receiver, uint16_t port) { std::lock_guard<std::mutex> lock(m_ReceiversMutex); m_ReceiversByPorts[port] = receiver; };
void ResetReceiver (uint16_t port) { m_ReceiversByPorts.erase (port); }; void ResetReceiver (uint16_t port) { std::lock_guard<std::mutex> lock(m_ReceiversMutex); m_ReceiversByPorts.erase (port); };
private: private:
// clean up after next tick // clean up after next tick
@ -96,12 +96,16 @@ namespace datagram
void HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
/** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */
Receiver FindReceiver(uint16_t port);
private: private:
i2p::client::ClientDestination * m_Owner; i2p::client::ClientDestination * m_Owner;
boost::asio::deadline_timer m_CleanupTimer; boost::asio::deadline_timer m_CleanupTimer;
Receiver m_Receiver; // default Receiver m_Receiver; // default
std::mutex m_SessionsMutex; std::mutex m_SessionsMutex;
std::map<i2p::data::IdentHash, std::shared_ptr<DatagramSession> > m_Sessions; std::map<i2p::data::IdentHash, std::shared_ptr<DatagramSession> > m_Sessions;
std::mutex m_ReceiversMutex;
std::map<uint16_t, Receiver> m_ReceiversByPorts; std::map<uint16_t, Receiver> m_ReceiversByPorts;
i2p::data::GzipInflator m_Inflator; i2p::data::GzipInflator m_Inflator;

9
Tag.h

@ -51,10 +51,11 @@ namespace data {
} }
/** fill with a value */ /** fill with a value */
void Fill(uint8_t c) { void Fill(uint8_t c)
memset(m_Buf, c, sz); {
} memset(m_Buf, c, sz);
}
std::string ToBase64 () const std::string ToBase64 () const
{ {
char str[sz*2]; char str[sz*2];

Loading…
Cancel
Save