mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-07 06:09:42 +00:00
Compare commits
56 Commits
0.2.0
...
0.3.0-home
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
335de27095 | ||
|
|
fa461b1254 | ||
|
|
81c63b0c30 | ||
|
|
dcefe7d221 | ||
|
|
ed3aaefe96 | ||
|
|
6042aefd17 | ||
|
|
1c3f70056a | ||
|
|
d8b9968aed | ||
|
|
8a357ac46c | ||
|
|
5187701af1 | ||
|
|
6cc3021baa | ||
|
|
0f4e4a7944 | ||
|
|
683c97d5c8 | ||
|
|
af2a5b93f2 | ||
|
|
f9ec60265a | ||
|
|
a449dc1377 | ||
|
|
f6849442a9 | ||
|
|
c3e329e406 | ||
|
|
69cbd71fe0 | ||
|
|
dd1a798128 | ||
|
|
96387aecbd | ||
|
|
77b7fff5ed | ||
|
|
72c0d8443a | ||
|
|
2988395b81 | ||
|
|
439b8798c9 | ||
|
|
7cf19f5784 | ||
|
|
b9e2b7bf64 | ||
|
|
cc14b526cd | ||
|
|
5e67bc62c1 | ||
|
|
692cde5151 | ||
|
|
4fbb823391 | ||
|
|
d636d55cc8 | ||
|
|
901eb10125 | ||
|
|
4b0001b442 | ||
|
|
3cd1281167 | ||
|
|
33f9918854 | ||
|
|
a518d6063c | ||
|
|
1232278c46 | ||
|
|
dd4283b7c1 | ||
|
|
3e826cd6dc | ||
|
|
2f8c37b132 | ||
|
|
e914d1640c | ||
|
|
25b5068f5e | ||
|
|
38b901484a | ||
|
|
c8a80a497d | ||
|
|
faf1fe7a7c | ||
|
|
f7791e5289 | ||
|
|
a8acb8ebb4 | ||
|
|
4334007688 | ||
|
|
7a976dd5f2 | ||
|
|
f28376bf71 | ||
|
|
3b435f1e1d | ||
|
|
a314feff33 | ||
|
|
0b77c9651b | ||
|
|
6b860c8c88 | ||
|
|
0cd04c23c5 |
13
Datagram.cpp
13
Datagram.cpp
@@ -13,7 +13,7 @@ namespace i2p
|
||||
namespace datagram
|
||||
{
|
||||
DatagramDestination::DatagramDestination (i2p::client::ClientDestination& owner):
|
||||
m_Owner (owner)
|
||||
m_Owner (owner), m_Receiver (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace datagram
|
||||
service->post (boost::bind (&DatagramDestination::SendMsg, this,
|
||||
CreateDataMessage (buf, len + headerLen), remote));
|
||||
else
|
||||
LogPrint ("Failed to send datagram. Destination is not running");
|
||||
LogPrint (eLogWarning, "Failed to send datagram. Destination is not running");
|
||||
}
|
||||
|
||||
void DatagramDestination::SendMsg (I2NPMessage * msg, const i2p::data::LeaseSet& remote)
|
||||
@@ -62,7 +62,7 @@ namespace datagram
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("Failed to send datagram. All leases expired");
|
||||
LogPrint (eLogWarning, "Failed to send datagram. All leases expired");
|
||||
DeleteI2NPMessage (msg);
|
||||
}
|
||||
}
|
||||
@@ -86,10 +86,13 @@ namespace datagram
|
||||
|
||||
if (verified)
|
||||
{
|
||||
// TODO: invoke datagram handler
|
||||
if (m_Receiver != nullptr)
|
||||
m_Receiver (identity, buf + headerLen, len -headerLen);
|
||||
else
|
||||
LogPrint (eLogWarning, "Receiver for datagram is not set");
|
||||
}
|
||||
else
|
||||
LogPrint ("Datagram signature verification failed");
|
||||
LogPrint (eLogWarning, "Datagram signature verification failed");
|
||||
}
|
||||
|
||||
void DatagramDestination::HandleDataMessagePayload (const uint8_t * buf, size_t len)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#define DATAGRAM_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <functional>
|
||||
#include "Identity.h"
|
||||
#include "LeaseSet.h"
|
||||
#include "I2NPProtocol.h"
|
||||
|
||||
@@ -16,6 +18,8 @@ namespace datagram
|
||||
const size_t MAX_DATAGRAM_SIZE = 32768;
|
||||
class DatagramDestination
|
||||
{
|
||||
typedef std::function<void (const i2p::data::IdentityEx& ident, const uint8_t *, size_t)> Receiver;
|
||||
|
||||
public:
|
||||
|
||||
DatagramDestination (i2p::client::ClientDestination& owner);
|
||||
@@ -24,6 +28,9 @@ namespace datagram
|
||||
void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::LeaseSet& remote);
|
||||
void HandleDataMessagePayload (const uint8_t * buf, size_t len);
|
||||
|
||||
void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; };
|
||||
void ResetReceiver () { m_Receiver = nullptr; };
|
||||
|
||||
private:
|
||||
|
||||
I2NPMessage * CreateDataMessage (const uint8_t * payload, size_t len);
|
||||
@@ -33,6 +40,7 @@ namespace datagram
|
||||
private:
|
||||
|
||||
i2p::client::ClientDestination& m_Owner;
|
||||
Receiver m_Receiver;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,12 @@ namespace client
|
||||
void ClientDestination::Stop ()
|
||||
{
|
||||
m_StreamingDestination->Stop ();
|
||||
if (m_DatagramDestination)
|
||||
{
|
||||
auto d = m_DatagramDestination;
|
||||
m_DatagramDestination = nullptr;
|
||||
delete d;
|
||||
}
|
||||
if (m_Pool)
|
||||
i2p::tunnel::tunnels.StopTunnelPool (m_Pool);
|
||||
m_IsRunning = false;
|
||||
@@ -275,7 +281,7 @@ namespace client
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ClientDestination::AcceptStreams (const std::function<void (i2p::stream::Stream *)>& acceptor)
|
||||
void ClientDestination::AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor)
|
||||
{
|
||||
if (m_StreamingDestination)
|
||||
m_StreamingDestination->SetAcceptor (acceptor);
|
||||
@@ -294,10 +300,11 @@ namespace client
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientDestination::CreateDatagramDestination ()
|
||||
i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination ()
|
||||
{
|
||||
if (!m_DatagramDestination)
|
||||
m_DatagramDestination = new i2p::datagram::DatagramDestination (*this);
|
||||
return m_DatagramDestination;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,13 +42,13 @@ namespace client
|
||||
// streaming
|
||||
i2p::stream::StreamingDestination * GetStreamingDestination () const { return m_StreamingDestination; };
|
||||
i2p::stream::Stream * CreateStream (const i2p::data::LeaseSet& remote, int port = 0);
|
||||
void AcceptStreams (const std::function<void (i2p::stream::Stream *)>& acceptor);
|
||||
void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor);
|
||||
void StopAcceptingStreams ();
|
||||
bool IsAcceptingStreams () const;
|
||||
|
||||
// datagram
|
||||
i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; };
|
||||
void CreateDatagramDestination ();
|
||||
i2p::datagram::DatagramDestination * CreateDatagramDestination ();
|
||||
|
||||
// implements LocalDestination
|
||||
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
|
||||
|
||||
31
Garlic.cpp
31
Garlic.cpp
@@ -148,7 +148,7 @@ namespace garlic
|
||||
size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, const I2NPMessage * msg)
|
||||
{
|
||||
size_t blockSize = 0;
|
||||
bool createNewTags = m_Owner && ((int)m_SessionTags.size () <= m_NumTags/2);
|
||||
bool createNewTags = m_Owner && m_NumTags && ((int)m_SessionTags.size () <= m_NumTags/2);
|
||||
UnconfirmedTags * newTags = createNewTags ? GenerateSessionTags () : nullptr;
|
||||
*(uint16_t *)buf = newTags ? htobe16 (newTags->numTags) : 0; // tag count
|
||||
blockSize += 2;
|
||||
@@ -272,6 +272,16 @@ namespace garlic
|
||||
size += 4;
|
||||
// create msg
|
||||
I2NPMessage * msg = CreateDeliveryStatusMsg (msgID);
|
||||
if (m_Owner)
|
||||
{
|
||||
//encrypt
|
||||
uint8_t key[32], tag[32];
|
||||
m_Rnd.GenerateBlock (key, 32); // random session key
|
||||
m_Rnd.GenerateBlock (tag, 32); // random session tag
|
||||
m_Owner->AddSessionKey (key, tag);
|
||||
GarlicRoutingSession garlic (key, tag);
|
||||
msg = garlic.WrapSingleMessage (msg);
|
||||
}
|
||||
memcpy (buf + size, msg->GetBuffer (), msg->GetLength ());
|
||||
size += msg->GetLength ();
|
||||
DeleteI2NPMessage (msg);
|
||||
@@ -304,9 +314,10 @@ namespace garlic
|
||||
{
|
||||
if (key)
|
||||
{
|
||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
auto decryption = std::make_shared<i2p::crypto::CBCDecryption>();
|
||||
decryption->SetKey (key);
|
||||
m_Tags[SessionTag(tag)] = decryption;
|
||||
m_Tags[SessionTag(tag, ts)] = decryption;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +325,7 @@ namespace garlic
|
||||
{
|
||||
uint8_t * buf = msg->GetPayload ();
|
||||
uint32_t length = be32toh (*(uint32_t *)buf);
|
||||
buf += 4; // lentgh
|
||||
buf += 4; // length
|
||||
auto it = m_Tags.find (SessionTag(buf));
|
||||
if (it != m_Tags.end ())
|
||||
{
|
||||
@@ -469,8 +480,16 @@ namespace garlic
|
||||
I2NPMessage * GarlicDestination::WrapMessage (const i2p::data::RoutingDestination& destination,
|
||||
I2NPMessage * msg, bool attachLeaseSet)
|
||||
{
|
||||
auto session = GetRoutingSession (destination, attachLeaseSet ? 32 : 0); // don't use tag if no LeaseSet
|
||||
return session->WrapSingleMessage (msg);
|
||||
if (attachLeaseSet) // we should maintain this session
|
||||
{
|
||||
auto session = GetRoutingSession (destination, 32); // 32 tags by default
|
||||
return session->WrapSingleMessage (msg);
|
||||
}
|
||||
else // one time session
|
||||
{
|
||||
GarlicRoutingSession session (this, &destination, 0); // don't use tag if no LeaseSet
|
||||
return session.WrapSingleMessage (msg);
|
||||
}
|
||||
}
|
||||
|
||||
GarlicRoutingSession * GarlicDestination::GetRoutingSession (
|
||||
@@ -488,7 +507,7 @@ namespace garlic
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
|
||||
void GarlicDestination::DeliveryStatusSent (GarlicRoutingSession * session, uint32_t msgID)
|
||||
{
|
||||
m_CreatedSessions[msgID] = session;
|
||||
|
||||
2
Garlic.h
2
Garlic.h
@@ -88,7 +88,7 @@ namespace garlic
|
||||
|
||||
GarlicDestination * m_Owner;
|
||||
const i2p::data::RoutingDestination * m_Destination;
|
||||
uint8_t m_SessionKey[32];
|
||||
i2p::crypto::AESKey m_SessionKey;
|
||||
std::list<SessionTag> m_SessionTags;
|
||||
int m_NumTags;
|
||||
std::map<uint32_t, UnconfirmedTags *> m_UnconfirmedTagsMsgs;
|
||||
|
||||
@@ -710,7 +710,7 @@ namespace util
|
||||
if (it.second && it.second->IsEstablished ())
|
||||
{
|
||||
// incoming connection doesn't have remote RI
|
||||
bool outgoing = it.second->GetRemoteRouter ();
|
||||
auto outgoing = it.second->GetRemoteRouter ();
|
||||
if (outgoing) s << "-->";
|
||||
s << it.second->GetRemoteIdentity ().GetIdentHash ().ToBase64 ().substr (0, 4) << ": "
|
||||
<< it.second->GetSocket ().remote_endpoint().address ().to_string ();
|
||||
@@ -727,7 +727,7 @@ namespace util
|
||||
for (auto it: ssuServer->GetSessions ())
|
||||
{
|
||||
// incoming connections don't have remote router
|
||||
bool outgoing = it.second->GetRemoteRouter ();
|
||||
auto outgoing = it.second->GetRemoteRouter ();
|
||||
auto endpoint = it.second->GetRemoteEndpoint ();
|
||||
if (outgoing) s << "-->";
|
||||
s << endpoint.address ().to_string () << ":" << endpoint.port ();
|
||||
|
||||
@@ -34,6 +34,14 @@ uint16_t be16toh(uint16_t big16);
|
||||
uint32_t be32toh(uint32_t big32);
|
||||
uint64_t be64toh(uint64_t big64);
|
||||
|
||||
// assume LittleEndine
|
||||
#define htole16
|
||||
#define htole32
|
||||
#define htole64
|
||||
#define le16toh
|
||||
#define le32toh
|
||||
#define le64toh
|
||||
|
||||
#endif
|
||||
|
||||
#endif // I2PENDIAN_H__
|
||||
|
||||
15
Identity.cpp
15
Identity.cpp
@@ -100,7 +100,7 @@ namespace data
|
||||
m_ExtendedBuffer = nullptr;
|
||||
|
||||
delete m_Verifier;
|
||||
CreateVerifier ();
|
||||
m_Verifier = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ namespace data
|
||||
m_ExtendedLen = 0;
|
||||
|
||||
delete m_Verifier;
|
||||
CreateVerifier ();
|
||||
m_Verifier = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -139,7 +139,7 @@ namespace data
|
||||
CryptoPP::SHA256().CalculateDigest(m_IdentHash, buf, GetFullLen ());
|
||||
|
||||
delete m_Verifier;
|
||||
CreateVerifier ();
|
||||
m_Verifier = nullptr;
|
||||
|
||||
return GetFullLen ();
|
||||
}
|
||||
@@ -161,19 +161,22 @@ namespace data
|
||||
|
||||
size_t IdentityEx::GetSigningPublicKeyLen () const
|
||||
{
|
||||
if (m_Verifier)
|
||||
if (!m_Verifier) CreateVerifier ();
|
||||
if (m_Verifier)
|
||||
return m_Verifier->GetPublicKeyLen ();
|
||||
return 128;
|
||||
}
|
||||
|
||||
size_t IdentityEx::GetSignatureLen () const
|
||||
{
|
||||
{
|
||||
if (!m_Verifier) CreateVerifier ();
|
||||
if (m_Verifier)
|
||||
return m_Verifier->GetSignatureLen ();
|
||||
return 40;
|
||||
}
|
||||
bool IdentityEx::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
|
||||
{
|
||||
if (!m_Verifier) CreateVerifier ();
|
||||
if (m_Verifier)
|
||||
return m_Verifier->Verify (buf, len, signature);
|
||||
return false;
|
||||
@@ -186,7 +189,7 @@ namespace data
|
||||
return SIGNING_KEY_TYPE_DSA_SHA1;
|
||||
}
|
||||
|
||||
void IdentityEx::CreateVerifier ()
|
||||
void IdentityEx::CreateVerifier () const
|
||||
{
|
||||
auto keyType = GetSigningKeyType ();
|
||||
switch (keyType)
|
||||
|
||||
@@ -134,13 +134,13 @@ namespace data
|
||||
|
||||
private:
|
||||
|
||||
void CreateVerifier ();
|
||||
void CreateVerifier () const;
|
||||
|
||||
private:
|
||||
|
||||
Identity m_StandardIdentity;
|
||||
IdentHash m_IdentHash;
|
||||
i2p::crypto::Verifier * m_Verifier;
|
||||
mutable i2p::crypto::Verifier * m_Verifier;
|
||||
size_t m_ExtendedLen;
|
||||
uint8_t * m_ExtendedBuffer;
|
||||
};
|
||||
|
||||
2
Makefile
2
Makefile
@@ -11,7 +11,7 @@ endif
|
||||
all: obj i2p
|
||||
|
||||
i2p: $(OBJECTS:obj/%=obj/%)
|
||||
$(CXX) -o $@ $^ $(LDFLAGS) $(LIBS)
|
||||
$(CXX) -o $@ $^ $(LDLIBS) $(LDFLAGS) $(LIBS)
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .cc .C .cpp .o
|
||||
|
||||
@@ -3,5 +3,6 @@ CXXFLAGS = -O2
|
||||
NEEDED_CXXFLAGS = -std=c++11
|
||||
include filelist.mk
|
||||
INCFLAGS = -I/usr/include/ -I/usr/local/include/
|
||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib -lcryptopp -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
|
||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||
LDLIBS = -lcryptopp -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
|
||||
LIBS =
|
||||
|
||||
@@ -3,7 +3,7 @@ CXXVER := $(shell $(CXX) -dumpversion)
|
||||
|
||||
FGREP = fgrep
|
||||
IS_64 := $(shell $(CXX) -dumpmachine 2>&1 | $(FGREP) -c "64")
|
||||
|
||||
USE_AESNI := yes
|
||||
ifeq ($(shell expr match ${CXXVER} "4\.[0-9][0-9]"),4) # >= 4.10
|
||||
NEEDED_CXXFLAGS += -std=c++11
|
||||
else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # >= 4.7
|
||||
@@ -16,17 +16,28 @@ else # not supported
|
||||
$(error Compiler too old)
|
||||
endif
|
||||
|
||||
LIBDIR := /usr/lib
|
||||
|
||||
include filelist.mk
|
||||
INCFLAGS =
|
||||
LDFLAGS = -lcryptopp -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
|
||||
ifeq ($(STATIC),yes)
|
||||
LDLIBS += $(LIBDIR)/libcryptopp.a $(LIBDIR)/libboost_system.a
|
||||
LDLIBS += $(LIBDIR)/libboost_date_time.a $(LIBDIR)/libboost_filesystem.a
|
||||
LDLIBS += $(LIBDIR)/libboost_regex.a $(LIBDIR)/libboost_program_options.a
|
||||
LDLIBS += -lpthread -static-libstdc++ -static-libgcc
|
||||
USE_AESNI := no
|
||||
else
|
||||
LDLIBS = -lcryptopp -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
|
||||
endif
|
||||
LIBS =
|
||||
|
||||
|
||||
ifeq ($(USE_AESNI),yes)
|
||||
ifeq ($(IS_64),1)
|
||||
#check if AES-NI is supported by CPU
|
||||
ifneq ($(shell grep -c aes /proc/cpuinfo),0)
|
||||
CPU_FLAGS = -maes -DAESNI
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
12
Makefile.osx
12
Makefile.osx
@@ -2,7 +2,8 @@ CXX = clang++
|
||||
CXXFLAGS = -g -Wall -std=c++11 -lstdc++ -I/usr/local/include
|
||||
include filelist.mk
|
||||
INCFLAGS = -DCRYPTOPP_DISABLE_ASM
|
||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib -lcryptopp -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
|
||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||
LDLIBS = -lcryptopp -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
|
||||
LIBS =
|
||||
|
||||
# OSX Notes
|
||||
@@ -11,6 +12,15 @@ LIBS =
|
||||
# Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic
|
||||
CXXFLAGS += -maes -DAESNI
|
||||
|
||||
|
||||
${PREFIX}:
|
||||
|
||||
install: all
|
||||
mkdir -p ${PREFIX}/
|
||||
cp -r i2p ${PREFIX}/
|
||||
|
||||
|
||||
|
||||
# Apple Mac OSX
|
||||
UNAME_S := $(shell uname -s)
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace i2p
|
||||
{
|
||||
namespace transport
|
||||
{
|
||||
NTCPSession::NTCPSession (boost::asio::io_service& service, const i2p::data::RouterInfo * in_RemoteRouter):
|
||||
NTCPSession::NTCPSession (boost::asio::io_service& service, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter):
|
||||
TransportSession (in_RemoteRouter), m_Socket (service),
|
||||
m_TerminationTimer (service), m_IsEstablished (false), m_ReceiveBufferOffset (0),
|
||||
m_NextMessage (nullptr), m_NumSentBytes (0), m_NumReceivedBytes (0)
|
||||
@@ -38,7 +38,7 @@ namespace transport
|
||||
m_DelayedMessages.clear ();
|
||||
}
|
||||
|
||||
void NTCPSession::CreateAESKey (uint8_t * pubKey, uint8_t * aesKey)
|
||||
void NTCPSession::CreateAESKey (uint8_t * pubKey, i2p::crypto::AESKey& key)
|
||||
{
|
||||
CryptoPP::DH dh (elgp, elgg);
|
||||
uint8_t sharedKey[256];
|
||||
@@ -49,6 +49,7 @@ namespace transport
|
||||
return;
|
||||
};
|
||||
|
||||
uint8_t * aesKey = key;
|
||||
if (sharedKey[0] & 0x80)
|
||||
{
|
||||
aesKey[0] = 0;
|
||||
@@ -201,7 +202,7 @@ namespace transport
|
||||
m_Establisher->phase2.encrypted.timestamp = tsB;
|
||||
// TODO: fill filler
|
||||
|
||||
uint8_t aesKey[32];
|
||||
i2p::crypto::AESKey aesKey;
|
||||
CreateAESKey (m_Establisher->phase1.pubKey, aesKey);
|
||||
m_Encryption.SetKey (aesKey);
|
||||
m_Encryption.SetIV (y + 240);
|
||||
@@ -249,7 +250,7 @@ namespace transport
|
||||
{
|
||||
LogPrint ("Phase 2 received: ", bytes_transferred);
|
||||
|
||||
uint8_t aesKey[32];
|
||||
i2p::crypto::AESKey aesKey;
|
||||
CreateAESKey (m_Establisher->phase2.pubKey, aesKey);
|
||||
m_Decryption.SetKey (aesKey);
|
||||
m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240);
|
||||
@@ -427,7 +428,7 @@ namespace transport
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint ("Read error: ", ecode.message ());
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
//if (ecode != boost::asio::error::operation_aborted)
|
||||
Terminate ();
|
||||
}
|
||||
else
|
||||
@@ -589,14 +590,15 @@ namespace transport
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
{
|
||||
LogPrint ("No activity fo ", NTCP_TERMINATION_TIMEOUT, " seconds");
|
||||
Terminate ();
|
||||
//Terminate ();
|
||||
m_Socket.close ();// invoke Terminate () from HandleReceive
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTCPClient::NTCPClient (boost::asio::io_service& service, const boost::asio::ip::address& address,
|
||||
int port, const i2p::data::RouterInfo& in_RouterInfo):
|
||||
NTCPSession (service, &in_RouterInfo), m_Endpoint (address, port)
|
||||
int port, std::shared_ptr<const i2p::data::RouterInfo> in_RouterInfo):
|
||||
NTCPSession (service, in_RouterInfo), m_Endpoint (address, port)
|
||||
{
|
||||
Connect ();
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace transport
|
||||
{
|
||||
public:
|
||||
|
||||
NTCPSession (boost::asio::io_service& service, const i2p::data::RouterInfo * in_RemoteRouter = nullptr);
|
||||
NTCPSession (boost::asio::io_service& service, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr);
|
||||
~NTCPSession ();
|
||||
|
||||
boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; };
|
||||
@@ -84,7 +84,7 @@ namespace transport
|
||||
|
||||
private:
|
||||
|
||||
void CreateAESKey (uint8_t * pubKey, uint8_t * aesKey);
|
||||
void CreateAESKey (uint8_t * pubKey, i2p::crypto::AESKey& key);
|
||||
|
||||
// client
|
||||
void SendPhase3 ();
|
||||
@@ -146,7 +146,7 @@ namespace transport
|
||||
{
|
||||
public:
|
||||
|
||||
NTCPClient (boost::asio::io_service& service, const boost::asio::ip::address& address, int port, const i2p::data::RouterInfo& in_RouterInfo);
|
||||
NTCPClient (boost::asio::io_service& service, const boost::asio::ip::address& address, int port, std::shared_ptr<const i2p::data::RouterInfo> in_RouterInfo);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
86
NetDb.cpp
86
NetDb.cpp
@@ -21,7 +21,7 @@ namespace i2p
|
||||
{
|
||||
namespace data
|
||||
{
|
||||
I2NPMessage * RequestedDestination::CreateRequestMessage (const RouterInfo * router,
|
||||
I2NPMessage * RequestedDestination::CreateRequestMessage (std::shared_ptr<const RouterInfo> router,
|
||||
const i2p::tunnel::InboundTunnel * replyTunnel)
|
||||
{
|
||||
I2NPMessage * msg = i2p::CreateDatabaseLookupMsg (m_Destination,
|
||||
@@ -71,8 +71,6 @@ namespace data
|
||||
Stop ();
|
||||
for (auto l:m_LeaseSets)
|
||||
delete l.second;
|
||||
for (auto r:m_RouterInfos)
|
||||
delete r.second;
|
||||
for (auto r:m_RequestedDestinations)
|
||||
delete r.second;
|
||||
}
|
||||
@@ -169,24 +167,27 @@ namespace data
|
||||
|
||||
void NetDb::AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len)
|
||||
{
|
||||
DeleteRequestedDestination (ident);
|
||||
auto it = m_RouterInfos.find(ident);
|
||||
if (it != m_RouterInfos.end ())
|
||||
DeleteRequestedDestination (ident);
|
||||
auto r = FindRouter (ident);
|
||||
if (r)
|
||||
{
|
||||
auto ts = it->second->GetTimestamp ();
|
||||
it->second->Update (buf, len);
|
||||
if (it->second->GetTimestamp () > ts)
|
||||
auto ts = r->GetTimestamp ();
|
||||
r->Update (buf, len);
|
||||
if (r->GetTimestamp () > ts)
|
||||
LogPrint ("RouterInfo updated");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("New RouterInfo added");
|
||||
RouterInfo * r = new RouterInfo (buf, len);
|
||||
m_RouterInfos[r->GetIdentHash ()] = r;
|
||||
if (r->IsFloodfill ())
|
||||
auto newRouter = std::make_shared<RouterInfo> (buf, len);
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
|
||||
m_RouterInfos[newRouter->GetIdentHash ()] = newRouter;
|
||||
}
|
||||
if (newRouter->IsFloodfill ())
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||
m_Floodfills.push_back (r);
|
||||
m_Floodfills.push_back (newRouter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,8 +212,9 @@ namespace data
|
||||
}
|
||||
}
|
||||
|
||||
RouterInfo * NetDb::FindRouter (const IdentHash& ident) const
|
||||
std::shared_ptr<RouterInfo> NetDb::FindRouter (const IdentHash& ident) const
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
|
||||
auto it = m_RouterInfos.find (ident);
|
||||
if (it != m_RouterInfos.end ())
|
||||
return it->second;
|
||||
@@ -271,8 +273,6 @@ namespace data
|
||||
if (!CreateNetDb(p)) return;
|
||||
}
|
||||
// make sure we cleanup netDb from previous attempts
|
||||
for (auto r: m_RouterInfos)
|
||||
delete r.second;
|
||||
m_RouterInfos.clear ();
|
||||
m_Floodfills.clear ();
|
||||
|
||||
@@ -291,7 +291,7 @@ namespace data
|
||||
#else
|
||||
const std::string& fullPath = it1->path();
|
||||
#endif
|
||||
RouterInfo * r = new RouterInfo(fullPath);
|
||||
auto r = std::make_shared<RouterInfo>(fullPath);
|
||||
if (!r->IsUnreachable () && (!r->UsesIntroducer () || ts < r->GetTimestamp () + 3600*1000LL)) // 1 hour
|
||||
{
|
||||
r->DeleteBuffer ();
|
||||
@@ -304,7 +304,6 @@ namespace data
|
||||
{
|
||||
if (boost::filesystem::exists (fullPath))
|
||||
boost::filesystem::remove (fullPath);
|
||||
delete r;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,7 +340,7 @@ namespace data
|
||||
{
|
||||
if (it.second->IsUpdated ())
|
||||
{
|
||||
it.second->SaveToFile (GetFilePath(fullDirectory, it.second));
|
||||
it.second->SaveToFile (GetFilePath(fullDirectory, it.second.get ()));
|
||||
it.second->SetUpdated (false);
|
||||
it.second->DeleteBuffer ();
|
||||
count++;
|
||||
@@ -359,18 +358,36 @@ namespace data
|
||||
|
||||
if (it.second->IsUnreachable ())
|
||||
{
|
||||
if (boost::filesystem::exists (GetFilePath (fullDirectory, it.second)))
|
||||
// delete RI file
|
||||
if (boost::filesystem::exists (GetFilePath (fullDirectory, it.second.get ())))
|
||||
{
|
||||
boost::filesystem::remove (GetFilePath (fullDirectory, it.second));
|
||||
boost::filesystem::remove (GetFilePath (fullDirectory, it.second.get ()));
|
||||
deletedCount++;
|
||||
}
|
||||
// delete from floodfills list
|
||||
if (it.second->IsFloodfill ())
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||
m_Floodfills.remove (it.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count > 0)
|
||||
LogPrint (count," new/updated routers saved");
|
||||
if (deletedCount > 0)
|
||||
{
|
||||
LogPrint (deletedCount," routers deleted");
|
||||
// clean up RouterInfos table
|
||||
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
|
||||
for (auto it = m_RouterInfos.begin (); it != m_RouterInfos.end ();)
|
||||
{
|
||||
if (it->second->IsUnreachable ())
|
||||
it = m_RouterInfos.erase (it);
|
||||
else
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetDb::RequestDestination (const IdentHash& destination, bool isLeaseSet, i2p::tunnel::TunnelPool * pool)
|
||||
@@ -616,7 +633,7 @@ namespace data
|
||||
LogPrint ("Requested RouterInfo ", key, " found");
|
||||
router->LoadBuffer ();
|
||||
if (router->GetBuffer ())
|
||||
replyMsg = CreateDatabaseStoreMsg (router);
|
||||
replyMsg = CreateDatabaseStoreMsg (router.get ());
|
||||
}
|
||||
}
|
||||
if (!replyMsg)
|
||||
@@ -638,7 +655,7 @@ namespace data
|
||||
excludedRouters.insert (excluded);
|
||||
excluded += 32;
|
||||
}
|
||||
replyMsg = CreateDatabaseSearchReply (buf, GetClosestFloodfill (buf, excludedRouters));
|
||||
replyMsg = CreateDatabaseSearchReply (buf, GetClosestFloodfill (buf, excludedRouters).get ());
|
||||
}
|
||||
else
|
||||
excluded += numExcluded*32; // we don't care about exluded
|
||||
@@ -702,9 +719,9 @@ namespace data
|
||||
rnd.GenerateBlock (randomHash, 32);
|
||||
RequestedDestination * dest = CreateRequestedDestination (IdentHash (randomHash), false, true, exploratoryPool);
|
||||
auto floodfill = GetClosestFloodfill (randomHash, dest->GetExcludedPeers ());
|
||||
if (floodfill && !floodfills.count (floodfill)) // request floodfill only once
|
||||
if (floodfill && !floodfills.count (floodfill.get ())) // request floodfill only once
|
||||
{
|
||||
floodfills.insert (floodfill);
|
||||
floodfills.insert (floodfill.get ());
|
||||
if (throughTunnels)
|
||||
{
|
||||
msgs.push_back (i2p::tunnel::TunnelMessageBlock
|
||||
@@ -783,29 +800,29 @@ namespace data
|
||||
}
|
||||
}
|
||||
|
||||
const RouterInfo * NetDb::GetRandomRouter () const
|
||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouter () const
|
||||
{
|
||||
return GetRandomRouter (
|
||||
[](const RouterInfo * router)->bool
|
||||
[](std::shared_ptr<const RouterInfo> router)->bool
|
||||
{
|
||||
return !router->IsHidden ();
|
||||
});
|
||||
}
|
||||
|
||||
const RouterInfo * NetDb::GetRandomRouter (const RouterInfo * compatibleWith) const
|
||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const
|
||||
{
|
||||
return GetRandomRouter (
|
||||
[compatibleWith](const RouterInfo * router)->bool
|
||||
[compatibleWith](std::shared_ptr<const RouterInfo> router)->bool
|
||||
{
|
||||
return !router->IsHidden () && router != compatibleWith &&
|
||||
router->IsCompatible (*compatibleWith);
|
||||
});
|
||||
}
|
||||
|
||||
const RouterInfo * NetDb::GetHighBandwidthRandomRouter (const RouterInfo * compatibleWith) const
|
||||
std::shared_ptr<const RouterInfo> NetDb::GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const
|
||||
{
|
||||
return GetRandomRouter (
|
||||
[compatibleWith](const RouterInfo * router)->bool
|
||||
[compatibleWith](std::shared_ptr<const RouterInfo> router)->bool
|
||||
{
|
||||
return !router->IsHidden () && router != compatibleWith &&
|
||||
router->IsCompatible (*compatibleWith) && (router->GetCaps () & RouterInfo::eHighBandwidth);
|
||||
@@ -813,13 +830,14 @@ namespace data
|
||||
}
|
||||
|
||||
template<typename Filter>
|
||||
const RouterInfo * NetDb::GetRandomRouter (Filter filter) const
|
||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouter (Filter filter) const
|
||||
{
|
||||
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
||||
uint32_t ind = rnd.GenerateWord32 (0, m_RouterInfos.size () - 1);
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
|
||||
for (auto it: m_RouterInfos)
|
||||
{
|
||||
if (i >= ind)
|
||||
@@ -841,10 +859,10 @@ namespace data
|
||||
if (msg) m_Queue.Put (msg);
|
||||
}
|
||||
|
||||
const RouterInfo * NetDb::GetClosestFloodfill (const IdentHash& destination,
|
||||
std::shared_ptr<const RouterInfo> NetDb::GetClosestFloodfill (const IdentHash& destination,
|
||||
const std::set<IdentHash>& excluded) const
|
||||
{
|
||||
RouterInfo * r = nullptr;
|
||||
std::shared_ptr<const RouterInfo> r;
|
||||
XORMetric minMetric;
|
||||
IdentHash destKey = CreateRoutingKey (destination);
|
||||
minMetric.SetMax ();
|
||||
|
||||
27
NetDb.h
27
NetDb.h
@@ -4,7 +4,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
@@ -27,19 +27,19 @@ namespace data
|
||||
RequestedDestination (const IdentHash& destination, bool isLeaseSet,
|
||||
bool isExploratory = false, i2p::tunnel::TunnelPool * pool = nullptr):
|
||||
m_Destination (destination), m_IsLeaseSet (isLeaseSet), m_IsExploratory (isExploratory),
|
||||
m_Pool (pool), m_LastRouter (nullptr), m_CreationTime (0) {};
|
||||
m_Pool (pool), m_CreationTime (0) {};
|
||||
|
||||
const IdentHash& GetDestination () const { return m_Destination; };
|
||||
int GetNumExcludedPeers () const { return m_ExcludedPeers.size (); };
|
||||
const std::set<IdentHash>& GetExcludedPeers () { return m_ExcludedPeers; };
|
||||
void ClearExcludedPeers ();
|
||||
const RouterInfo * GetLastRouter () const { return m_LastRouter; };
|
||||
std::shared_ptr<const RouterInfo> GetLastRouter () const { return m_LastRouter; };
|
||||
i2p::tunnel::TunnelPool * GetTunnelPool () { return m_Pool; };
|
||||
bool IsExploratory () const { return m_IsExploratory; };
|
||||
bool IsLeaseSet () const { return m_IsLeaseSet; };
|
||||
bool IsExcluded (const IdentHash& ident) const { return m_ExcludedPeers.count (ident); };
|
||||
uint64_t GetCreationTime () const { return m_CreationTime; };
|
||||
I2NPMessage * CreateRequestMessage (const RouterInfo * router, const i2p::tunnel::InboundTunnel * replyTunnel);
|
||||
I2NPMessage * CreateRequestMessage (std::shared_ptr<const RouterInfo>, const i2p::tunnel::InboundTunnel * replyTunnel);
|
||||
I2NPMessage * CreateRequestMessage (const IdentHash& floodfill);
|
||||
|
||||
private:
|
||||
@@ -48,7 +48,7 @@ namespace data
|
||||
bool m_IsLeaseSet, m_IsExploratory;
|
||||
i2p::tunnel::TunnelPool * m_Pool;
|
||||
std::set<IdentHash> m_ExcludedPeers;
|
||||
const RouterInfo * m_LastRouter;
|
||||
std::shared_ptr<const RouterInfo> m_LastRouter;
|
||||
uint64_t m_CreationTime;
|
||||
};
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace data
|
||||
|
||||
void AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len);
|
||||
void AddLeaseSet (const IdentHash& ident, const uint8_t * buf, int len, i2p::tunnel::InboundTunnel * from);
|
||||
RouterInfo * FindRouter (const IdentHash& ident) const;
|
||||
std::shared_ptr<RouterInfo> FindRouter (const IdentHash& ident) const;
|
||||
LeaseSet * FindLeaseSet (const IdentHash& destination) const;
|
||||
|
||||
void PublishLeaseSet (const LeaseSet * leaseSet, i2p::tunnel::TunnelPool * pool);
|
||||
@@ -75,9 +75,9 @@ namespace data
|
||||
void HandleDatabaseSearchReplyMsg (I2NPMessage * msg);
|
||||
void HandleDatabaseLookupMsg (I2NPMessage * msg);
|
||||
|
||||
const RouterInfo * GetRandomRouter () const;
|
||||
const RouterInfo * GetRandomRouter (const RouterInfo * compatibleWith) const;
|
||||
const RouterInfo * GetHighBandwidthRandomRouter (const RouterInfo * compatibleWith) const;
|
||||
std::shared_ptr<const RouterInfo> GetRandomRouter () const;
|
||||
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const;
|
||||
std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const;
|
||||
void SetUnreachable (const IdentHash& ident, bool unreachable);
|
||||
|
||||
void PostI2NPMsg (I2NPMessage * msg);
|
||||
@@ -95,7 +95,7 @@ namespace data
|
||||
void Run (); // exploratory thread
|
||||
void Explore (int numDestinations);
|
||||
void Publish ();
|
||||
const RouterInfo * GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
|
||||
std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
|
||||
void ManageLeaseSets ();
|
||||
|
||||
RequestedDestination * CreateRequestedDestination (const IdentHash& dest,
|
||||
@@ -104,14 +104,15 @@ namespace data
|
||||
void DeleteRequestedDestination (RequestedDestination * dest);
|
||||
|
||||
template<typename Filter>
|
||||
const RouterInfo * GetRandomRouter (Filter filter) const;
|
||||
std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const;
|
||||
|
||||
private:
|
||||
|
||||
std::map<IdentHash, LeaseSet *> m_LeaseSets;
|
||||
std::map<IdentHash, RouterInfo *> m_RouterInfos;
|
||||
mutable std::mutex m_RouterInfosMutex;
|
||||
std::map<IdentHash, std::shared_ptr<RouterInfo> > m_RouterInfos;
|
||||
mutable std::mutex m_FloodfillsMutex;
|
||||
std::vector<RouterInfo *> m_Floodfills;
|
||||
std::list<std::shared_ptr<RouterInfo> > m_Floodfills;
|
||||
std::mutex m_RequestedDestinationsMutex;
|
||||
std::map<IdentHash, RequestedDestination *> m_RequestedDestinations;
|
||||
|
||||
|
||||
37
README.md
37
README.md
@@ -1,21 +1,28 @@
|
||||
i2pd
|
||||
====
|
||||
|
||||
i2p router for Linux written on C++
|
||||
I2P router written in C++
|
||||
|
||||
Requires gcc 4.6 and higher, boost 1.46 and higher, crypto++
|
||||
Requirements for Linux/FreeBSD/OSX
|
||||
----------------------------------
|
||||
|
||||
on Windows
|
||||
GCC 4.6 or newer, Boost 1.46 or newer, crypto++. Clang can be used instead of
|
||||
GCC.
|
||||
|
||||
Requires msvs2013 (require Visual C++ Compiler November 2013 CTP update), boost 1.46 and higher, crypto++
|
||||
Requirements for Windows
|
||||
------------------------
|
||||
|
||||
VS2013 (known to work with 12.0.21005.1 or newer), Boost 1.46 or newer,
|
||||
crypto++ 5.62. See Win32/README-Build.txt for instructions on how to build i2pd
|
||||
and its dependencies.
|
||||
|
||||
Build Statuses
|
||||
---------------
|
||||
|
||||
- Linux x64 - [](https://jenkins.nordcloud.no/job/i2pd-linux/)
|
||||
- Linux ARM - Too be added
|
||||
- Mac OS X - Too be added
|
||||
- Microsoft VC13 - Too be added
|
||||
- Linux ARM - To be added
|
||||
- Mac OS X - To be added
|
||||
- Microsoft VC13 - To be added
|
||||
|
||||
|
||||
Testing
|
||||
@@ -51,14 +58,14 @@ Options
|
||||
* --daemon= - Enable or disable daemon mode. 1 for yes, 0 for no.
|
||||
* --service= - 1 if uses system folders (/var/run/i2pd.pid, /var/log/i2pd.log, /var/lib/i2pd).
|
||||
* --unreachable= - 1 if router is declared as unreachable and works through introducers.
|
||||
* --v6= - 1 if supports communication through ipv6, off by default
|
||||
* --v6= - 1 if supports communication through ipv6, off by default
|
||||
* --httpproxyport= - The port to listen on (HTTP Proxy)
|
||||
* --socksproxyport= - The port to listen on (SOCKS Proxy)
|
||||
* --ircport= - The local port of IRC tunnel to listen on. 6668 by default
|
||||
* --ircdest= - I2P destination address of IRC server. For example irc.postman.i2p
|
||||
* --irckeys= - optional keys file for local destination
|
||||
* --eepkeys= - File name containing destination keys. For example privKeys.dat
|
||||
* --eephost= - Address incoming trafic forward to. 127.0.0.1 by default
|
||||
* --eepport= - Port incoming trafic forward to. 80 by default
|
||||
* --samport= - Port of SAM bridge. Usually 7656. SAM is off if not specified
|
||||
* --ircport= - The local port of IRC tunnel to listen on. 6668 by default
|
||||
* --ircdest= - I2P destination address of IRC server. For example irc.postman.i2p
|
||||
* --irckeys= - optional keys file for local destination
|
||||
* --eepkeys= - File name containing destination keys. For example privKeys.dat
|
||||
* --eephost= - Address incoming trafic forward to. 127.0.0.1 by default
|
||||
* --eepport= - Port incoming trafic forward to. 80 by default
|
||||
* --samport= - Port of SAM bridge. Usually 7656. SAM is off if not specified
|
||||
|
||||
|
||||
55
Reseed.cpp
55
Reseed.cpp
@@ -2,6 +2,8 @@
|
||||
#include <fstream>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <cryptopp/gzip.h>
|
||||
#include "I2PEndian.h"
|
||||
#include "Reseed.h"
|
||||
#include "Log.h"
|
||||
#include "util.h"
|
||||
@@ -119,6 +121,59 @@ namespace data
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProcessSU3File (const char * filename)
|
||||
{
|
||||
static uint32_t headerSignature = htole32 (0x04044B50);
|
||||
|
||||
std::ifstream s(filename, std::ifstream::binary);
|
||||
if (s.is_open ())
|
||||
{
|
||||
while (!s.eof ())
|
||||
{
|
||||
uint32_t signature;
|
||||
s.read ((char *)&signature, 4);
|
||||
if (signature == headerSignature)
|
||||
{
|
||||
// next local file
|
||||
s.seekg (14, std::ios::cur); // skip field we don't care about
|
||||
uint32_t compressedSize, uncompressedSize;
|
||||
s.read ((char *)&compressedSize, 4);
|
||||
compressedSize = le32toh (compressedSize);
|
||||
s.read ((char *)&uncompressedSize, 4);
|
||||
uncompressedSize = le32toh (uncompressedSize);
|
||||
uint16_t fileNameLength, extraFieldLength;
|
||||
s.read ((char *)&fileNameLength, 2);
|
||||
fileNameLength = le32toh (fileNameLength);
|
||||
s.read ((char *)&extraFieldLength, 2);
|
||||
extraFieldLength = le32toh (extraFieldLength);
|
||||
char localFileName[255];
|
||||
s.read (localFileName, fileNameLength);
|
||||
localFileName[fileNameLength] = 0;
|
||||
s.seekg (extraFieldLength, std::ios::cur);
|
||||
|
||||
uint8_t * compressed = new uint8_t[compressedSize];
|
||||
s.read ((char *)compressed, compressedSize);
|
||||
CryptoPP::Gunzip decompressor;
|
||||
decompressor.Put (compressed, compressedSize);
|
||||
delete[] compressed;
|
||||
if (decompressor.MaxRetrievable () <= uncompressedSize)
|
||||
{
|
||||
uint8_t * uncompressed = new uint8_t[uncompressedSize];
|
||||
decompressor.Get (uncompressed, decompressor.MaxRetrievable ());
|
||||
// TODO: save file
|
||||
delete[] uncompressed;
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Actual uncompressed size ", decompressor.MaxRetrievable (), " exceed ", uncompressedSize, " from header");
|
||||
}
|
||||
else
|
||||
break; // no more files
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Can't open file ", filename);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
3
Reseed.h
3
Reseed.h
@@ -17,7 +17,8 @@ namespace data
|
||||
bool reseedNow();
|
||||
};
|
||||
|
||||
void ProcessSU3File (const char * filename);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace i2p
|
||||
void RouterContext::NewRouterInfo ()
|
||||
{
|
||||
i2p::data::RouterInfo routerInfo;
|
||||
routerInfo.SetRouterIdentity (GetIdentity ().GetStandardIdentity ());
|
||||
routerInfo.SetRouterIdentity (GetIdentity ());
|
||||
int port = i2p::util::config::GetArg("-port", 0);
|
||||
if (!port)
|
||||
port = m_Rnd.GenerateWord32 (9111, 30777); // I2P network ports range
|
||||
@@ -162,7 +162,13 @@ namespace i2p
|
||||
{
|
||||
// create new address
|
||||
m_RouterInfo.AddNTCPAddress (host.to_string ().c_str (), port);
|
||||
m_RouterInfo.AddSSUAddress (host.to_string ().c_str (), port, GetIdentHash (), 1472); // TODO
|
||||
auto mtu = i2p::util::net::GetMTU (host);
|
||||
if (mtu)
|
||||
{
|
||||
LogPrint ("Our v6 MTU=", mtu);
|
||||
if (mtu > 1472) mtu = 1472;
|
||||
}
|
||||
m_RouterInfo.AddSSUAddress (host.to_string ().c_str (), port, GetIdentHash (), mtu ? mtu : 1472); // TODO
|
||||
updated = true;
|
||||
}
|
||||
if (updated)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <boost/asio.hpp>
|
||||
#include <cryptopp/dsa.h>
|
||||
#include <cryptopp/osrng.h>
|
||||
@@ -24,6 +25,11 @@ namespace i2p
|
||||
void Init ();
|
||||
|
||||
i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; };
|
||||
std::shared_ptr<const i2p::data::RouterInfo> GetSharedRouterInfo () const
|
||||
{
|
||||
return std::shared_ptr<const i2p::data::RouterInfo> (&m_RouterInfo,
|
||||
[](const i2p::data::RouterInfo *) {});
|
||||
}
|
||||
CryptoPP::RandomNumberGenerator& GetRandomNumberGenerator () { return m_Rnd; };
|
||||
|
||||
void UpdatePort (int port); // called from Daemon
|
||||
|
||||
@@ -55,10 +55,9 @@ namespace data
|
||||
// don't delete buffer until save to file
|
||||
}
|
||||
|
||||
void RouterInfo::SetRouterIdentity (const Identity& identity)
|
||||
void RouterInfo::SetRouterIdentity (const IdentityEx& identity)
|
||||
{
|
||||
m_RouterIdentity = identity;
|
||||
m_IdentHash = m_RouterIdentity.Hash ();
|
||||
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
}
|
||||
|
||||
@@ -95,31 +94,20 @@ namespace data
|
||||
|
||||
void RouterInfo::ReadFromBuffer (bool verifySignature)
|
||||
{
|
||||
std::stringstream str (std::string ((char *)m_Buffer, m_BufferLen));
|
||||
size_t identityLen = m_RouterIdentity.FromBuffer (m_Buffer, m_BufferLen);
|
||||
std::stringstream str (std::string ((char *)m_Buffer + identityLen, m_BufferLen - identityLen));
|
||||
ReadFromStream (str);
|
||||
if (verifySignature)
|
||||
{
|
||||
// verify signature
|
||||
CryptoPP::DSA::PublicKey pubKey;
|
||||
pubKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, CryptoPP::Integer (m_RouterIdentity.signingKey, 128));
|
||||
CryptoPP::DSA::Verifier verifier (pubKey);
|
||||
int l = m_BufferLen - 40;
|
||||
if (!verifier.VerifyMessage ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l, 40))
|
||||
{
|
||||
int l = m_BufferLen - m_RouterIdentity.GetSignatureLen ();
|
||||
if (!m_RouterIdentity.Verify ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l))
|
||||
LogPrint (eLogError, "signature verification failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RouterInfo::ReadFromStream (std::istream& s)
|
||||
{
|
||||
s.read ((char *)&m_RouterIdentity, DEFAULT_IDENTITY_SIZE);
|
||||
if (m_RouterIdentity.certificate.type != CERTIFICATE_TYPE_NULL)
|
||||
{
|
||||
LogPrint (eLogError, "Certificate type ", m_RouterIdentity.certificate.type, " is not supported");
|
||||
SetUnreachable (true);
|
||||
return;
|
||||
}
|
||||
s.read ((char *)&m_Timestamp, sizeof (m_Timestamp));
|
||||
m_Timestamp = be64toh (m_Timestamp);
|
||||
// read addresses
|
||||
@@ -232,8 +220,6 @@ namespace data
|
||||
if (!strcmp (key, "caps"))
|
||||
ExtractCaps (value);
|
||||
}
|
||||
|
||||
CryptoPP::SHA256().CalculateDigest(m_IdentHash, (uint8_t *)&m_RouterIdentity, sizeof (m_RouterIdentity));
|
||||
|
||||
if (!m_SupportedTransports || !m_Addresses.size() || (UsesIntroducer () && !introducers))
|
||||
SetUnreachable (true);
|
||||
|
||||
15
RouterInfo.h
15
RouterInfo.h
@@ -90,10 +90,10 @@ namespace data
|
||||
RouterInfo (const uint8_t * buf, int len);
|
||||
~RouterInfo ();
|
||||
|
||||
const Identity& GetRouterIdentity () const { return m_RouterIdentity; };
|
||||
void SetRouterIdentity (const Identity& identity);
|
||||
std::string GetIdentHashBase64 () const { return m_IdentHash.ToBase64 (); };
|
||||
std::string GetIdentHashAbbreviation () const { return m_IdentHash.ToBase64 ().substr (0, 4); };
|
||||
const IdentityEx& GetRouterIdentity () const { return m_RouterIdentity; };
|
||||
void SetRouterIdentity (const IdentityEx& identity);
|
||||
std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
|
||||
std::string GetIdentHashAbbreviation () const { return GetIdentHash ().ToBase64 ().substr (0, 4); };
|
||||
uint64_t GetTimestamp () const { return m_Timestamp; };
|
||||
std::vector<Address>& GetAddresses () { return m_Addresses; };
|
||||
const Address * GetNTCPAddress (bool v4only = true) const;
|
||||
@@ -138,8 +138,8 @@ namespace data
|
||||
void DeleteBuffer () { delete m_Buffer; m_Buffer = nullptr; };
|
||||
|
||||
// implements RoutingDestination
|
||||
const IdentHash& GetIdentHash () const { return m_IdentHash; };
|
||||
const uint8_t * GetEncryptionPublicKey () const { return m_RouterIdentity.publicKey; };
|
||||
const IdentHash& GetIdentHash () const { return m_RouterIdentity.GetIdentHash (); };
|
||||
const uint8_t * GetEncryptionPublicKey () const { return m_RouterIdentity.GetStandardIdentity ().publicKey; };
|
||||
bool IsDestination () const { return false; };
|
||||
|
||||
|
||||
@@ -159,8 +159,7 @@ namespace data
|
||||
private:
|
||||
|
||||
std::string m_FullPath;
|
||||
Identity m_RouterIdentity;
|
||||
IdentHash m_IdentHash;
|
||||
IdentityEx m_RouterIdentity;
|
||||
uint8_t * m_Buffer;
|
||||
int m_BufferLen;
|
||||
uint64_t m_Timestamp;
|
||||
|
||||
101
SAM.cpp
101
SAM.cpp
@@ -26,21 +26,18 @@ namespace client
|
||||
SAMSocket::~SAMSocket ()
|
||||
{
|
||||
if (m_Stream)
|
||||
{
|
||||
m_Stream->Close ();
|
||||
i2p::stream::DeleteStream (m_Stream);
|
||||
m_Stream = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SAMSocket::Terminate ()
|
||||
{
|
||||
if (m_Stream)
|
||||
{
|
||||
m_Stream->Close ();
|
||||
i2p::stream::DeleteStream (m_Stream);
|
||||
m_Stream = nullptr;
|
||||
}
|
||||
|
||||
// TODO: make this swap atomic
|
||||
auto session = m_Session;
|
||||
m_Session = nullptr;
|
||||
|
||||
switch (m_SocketType)
|
||||
{
|
||||
case eSAMSocketTypeSession:
|
||||
@@ -48,16 +45,16 @@ namespace client
|
||||
break;
|
||||
case eSAMSocketTypeStream:
|
||||
{
|
||||
if (m_Session)
|
||||
m_Session->sockets.remove (this);
|
||||
if (session)
|
||||
session->sockets.remove (shared_from_this ());
|
||||
break;
|
||||
}
|
||||
case eSAMSocketTypeAcceptor:
|
||||
{
|
||||
if (m_Session)
|
||||
if (session)
|
||||
{
|
||||
m_Session->sockets.remove (this);
|
||||
m_Session->localDestination->StopAcceptingStreams ();
|
||||
session->sockets.remove (shared_from_this ());
|
||||
session->localDestination->StopAcceptingStreams ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -65,13 +62,12 @@ namespace client
|
||||
;
|
||||
}
|
||||
m_Socket.close ();
|
||||
// delete this;
|
||||
}
|
||||
|
||||
void SAMSocket::ReceiveHandshake ()
|
||||
{
|
||||
m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
|
||||
boost::bind(&SAMSocket::HandleHandshakeReceived, this,
|
||||
boost::bind(&SAMSocket::HandleHandshakeReceived, shared_from_this (),
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
@@ -91,7 +87,7 @@ namespace client
|
||||
{
|
||||
// TODO: check version
|
||||
boost::asio::async_write (m_Socket, boost::asio::buffer (SAM_HANDSHAKE_REPLY, strlen (SAM_HANDSHAKE_REPLY)), boost::asio::transfer_all (),
|
||||
boost::bind(&SAMSocket::HandleHandshakeReplySent, this,
|
||||
boost::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (),
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
else
|
||||
@@ -113,7 +109,7 @@ namespace client
|
||||
else
|
||||
{
|
||||
m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
|
||||
boost::bind(&SAMSocket::HandleMessage, this,
|
||||
boost::bind(&SAMSocket::HandleMessage, shared_from_this (),
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
}
|
||||
@@ -122,7 +118,7 @@ namespace client
|
||||
{
|
||||
if (!m_IsSilent || m_SocketType == eSAMSocketTypeAcceptor)
|
||||
boost::asio::async_write (m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (),
|
||||
boost::bind(&SAMSocket::HandleMessageReplySent, this,
|
||||
boost::bind(&SAMSocket::HandleMessageReplySent, shared_from_this (),
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, close));
|
||||
else
|
||||
{
|
||||
@@ -226,14 +222,18 @@ namespace client
|
||||
if (m_Session->localDestination->IsReady ())
|
||||
{
|
||||
if (style == SAM_VALUE_DATAGRAM)
|
||||
m_Session->localDestination->CreateDatagramDestination ();
|
||||
{
|
||||
auto dest = m_Session->localDestination->CreateDatagramDestination ();
|
||||
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
|
||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
}
|
||||
SendSessionCreateReplyOk ();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Timer.expires_from_now (boost::posix_time::seconds(SAM_SESSION_READINESS_CHECK_INTERVAL));
|
||||
m_Timer.async_wait (boost::bind (&SAMSocket::HandleSessionReadinessCheckTimer,
|
||||
this, boost::asio::placeholders::error));
|
||||
shared_from_this (), boost::asio::placeholders::error));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -250,7 +250,7 @@ namespace client
|
||||
{
|
||||
m_Timer.expires_from_now (boost::posix_time::seconds(SAM_SESSION_READINESS_CHECK_INTERVAL));
|
||||
m_Timer.async_wait (boost::bind (&SAMSocket::HandleSessionReadinessCheckTimer,
|
||||
this, boost::asio::placeholders::error));
|
||||
shared_from_this (), boost::asio::placeholders::error));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,7 +295,7 @@ namespace client
|
||||
i2p::data::netdb.RequestDestination (dest.GetIdentHash (), true, m_Session->localDestination->GetTunnelPool ());
|
||||
m_Timer.expires_from_now (boost::posix_time::seconds(SAM_CONNECT_TIMEOUT));
|
||||
m_Timer.async_wait (boost::bind (&SAMSocket::HandleStreamDestinationRequestTimer,
|
||||
this, boost::asio::placeholders::error, dest.GetIdentHash ()));
|
||||
shared_from_this (), boost::asio::placeholders::error, dest.GetIdentHash ()));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -305,7 +305,7 @@ namespace client
|
||||
void SAMSocket::Connect (const i2p::data::LeaseSet& remote)
|
||||
{
|
||||
m_SocketType = eSAMSocketTypeStream;
|
||||
m_Session->sockets.push_back (this);
|
||||
m_Session->sockets.push_back (shared_from_this ());
|
||||
m_Stream = m_Session->localDestination->CreateStream (remote);
|
||||
m_Stream->Send ((uint8_t *)m_Buffer, 0); // connect
|
||||
I2PReceive ();
|
||||
@@ -362,8 +362,8 @@ namespace client
|
||||
if (!m_Session->localDestination->IsAcceptingStreams ())
|
||||
{
|
||||
m_SocketType = eSAMSocketTypeAcceptor;
|
||||
m_Session->sockets.push_back (this);
|
||||
m_Session->localDestination->AcceptStreams (std::bind (&SAMSocket::HandleI2PAccept, this, std::placeholders::_1));
|
||||
m_Session->sockets.push_back (shared_from_this ());
|
||||
m_Session->localDestination->AcceptStreams (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1));
|
||||
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
|
||||
}
|
||||
else
|
||||
@@ -418,7 +418,7 @@ namespace client
|
||||
i2p::data::netdb.RequestDestination (ident, true, m_Session->localDestination->GetTunnelPool ());
|
||||
m_Timer.expires_from_now (boost::posix_time::seconds(SAM_NAMING_LOOKUP_TIMEOUT));
|
||||
m_Timer.async_wait (boost::bind (&SAMSocket::HandleNamingLookupDestinationRequestTimer,
|
||||
this, boost::asio::placeholders::error, ident));
|
||||
shared_from_this (), boost::asio::placeholders::error, ident));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -471,7 +471,7 @@ namespace client
|
||||
{
|
||||
m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
|
||||
boost::bind((m_SocketType == eSAMSocketTypeSession) ? &SAMSocket::HandleMessage : &SAMSocket::HandleReceived,
|
||||
this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
shared_from_this (), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void SAMSocket::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||
@@ -494,7 +494,7 @@ namespace client
|
||||
{
|
||||
if (m_Stream)
|
||||
m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE),
|
||||
boost::bind (&SAMSocket::HandleI2PReceive, this,
|
||||
boost::bind (&SAMSocket::HandleI2PReceive, shared_from_this (),
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred),
|
||||
SAM_SOCKET_CONNECTION_MAX_IDLE);
|
||||
}
|
||||
@@ -510,7 +510,7 @@ namespace client
|
||||
else
|
||||
{
|
||||
boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred),
|
||||
boost::bind (&SAMSocket::HandleWriteI2PData, this, boost::asio::placeholders::error));
|
||||
boost::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), boost::asio::placeholders::error));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,18 +548,37 @@ namespace client
|
||||
}
|
||||
}
|
||||
|
||||
void SAMSocket::HandleI2PDatagramReceive (const i2p::data::IdentityEx& ident, const uint8_t * buf, size_t len)
|
||||
{
|
||||
uint8_t identBuf[1024];
|
||||
size_t l = ident.ToBuffer (identBuf, 1024);
|
||||
size_t l1 = i2p::data::ByteStreamToBase64 (identBuf, l, m_Buffer, SAM_SOCKET_BUFFER_SIZE);
|
||||
m_Buffer[l1] = 0;
|
||||
#ifdef _MSC_VER
|
||||
size_t l2 = sprintf_s ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, m_Buffer, len);
|
||||
#else
|
||||
size_t l2 = snprintf ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, m_Buffer, len);
|
||||
#endif
|
||||
if (len < SAM_SOCKET_BUFFER_SIZE - l2)
|
||||
{
|
||||
memcpy (m_StreamBuffer + l2, buf, len);
|
||||
boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, len + l2),
|
||||
boost::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), boost::asio::placeholders::error));
|
||||
}
|
||||
else
|
||||
LogPrint (eLogWarning, "Datagram size ", len," exceeds buffer");
|
||||
}
|
||||
|
||||
SAMBridge::SAMBridge (int port):
|
||||
m_IsRunning (false), m_Thread (nullptr),
|
||||
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
|
||||
m_DatagramEndpoint (boost::asio::ip::udp::v4 (), port-1), m_DatagramSocket (m_Service, m_DatagramEndpoint),
|
||||
m_NewSocket (nullptr)
|
||||
m_DatagramEndpoint (boost::asio::ip::udp::v4 (), port-1), m_DatagramSocket (m_Service, m_DatagramEndpoint)
|
||||
{
|
||||
}
|
||||
|
||||
SAMBridge::~SAMBridge ()
|
||||
{
|
||||
Stop ();
|
||||
delete m_NewSocket;
|
||||
}
|
||||
|
||||
void SAMBridge::Start ()
|
||||
@@ -599,24 +618,20 @@ namespace client
|
||||
|
||||
void SAMBridge::Accept ()
|
||||
{
|
||||
m_NewSocket = new SAMSocket (*this);
|
||||
m_Acceptor.async_accept (m_NewSocket->GetSocket (), boost::bind (&SAMBridge::HandleAccept, this,
|
||||
boost::asio::placeholders::error));
|
||||
auto newSocket = std::make_shared<SAMSocket> (*this);
|
||||
m_Acceptor.async_accept (newSocket->GetSocket (), boost::bind (&SAMBridge::HandleAccept, this,
|
||||
boost::asio::placeholders::error, newSocket));
|
||||
}
|
||||
|
||||
void SAMBridge::HandleAccept(const boost::system::error_code& ecode)
|
||||
void SAMBridge::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<SAMSocket> socket)
|
||||
{
|
||||
if (!ecode)
|
||||
{
|
||||
LogPrint ("New SAM connection from ", m_NewSocket->GetSocket ().remote_endpoint ());
|
||||
m_NewSocket->ReceiveHandshake ();
|
||||
LogPrint ("New SAM connection from ", socket->GetSocket ().remote_endpoint ());
|
||||
socket->ReceiveHandshake ();
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("SAM accept error: ", ecode.message ());
|
||||
delete m_NewSocket;
|
||||
m_NewSocket = nullptr;
|
||||
}
|
||||
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
Accept ();
|
||||
@@ -655,8 +670,6 @@ namespace client
|
||||
auto it = m_Sessions.find (id);
|
||||
if (it != m_Sessions.end ())
|
||||
{
|
||||
for (auto it1 : it->second.sockets)
|
||||
delete it1;
|
||||
it->second.sockets.clear ();
|
||||
it->second.localDestination->Stop ();
|
||||
m_Sessions.erase (it);
|
||||
|
||||
10
SAM.h
10
SAM.h
@@ -7,6 +7,7 @@
|
||||
#include <list>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <boost/asio.hpp>
|
||||
#include "Identity.h"
|
||||
#include "LeaseSet.h"
|
||||
@@ -39,6 +40,7 @@ namespace client
|
||||
const char SAM_DEST_REPLY_I2P_ERROR[] = "DEST REPLY RESULT=I2P_ERROR\n";
|
||||
const char SAM_NAMING_LOOKUP[] = "NAMING LOOKUP";
|
||||
const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=ME VALUE=%s\n";
|
||||
const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM_RECEIVED DESTINATION=%s SIZE=%lu\n";
|
||||
const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n";
|
||||
const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=INVALID_KEY_NOT_FOUND NAME=%s\n";
|
||||
const char SAM_PARAM_STYLE[] = "STYLE";
|
||||
@@ -63,7 +65,7 @@ namespace client
|
||||
|
||||
class SAMBridge;
|
||||
class SAMSession;
|
||||
class SAMSocket
|
||||
class SAMSocket: public std::enable_shared_from_this<SAMSocket>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -88,6 +90,7 @@ namespace client
|
||||
void HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void HandleI2PAccept (i2p::stream::Stream * stream);
|
||||
void HandleWriteI2PData (const boost::system::error_code& ecode);
|
||||
void HandleI2PDatagramReceive (const i2p::data::IdentityEx& ident, const uint8_t * buf, size_t len);
|
||||
|
||||
void ProcessSessionCreate (char * buf, size_t len);
|
||||
void ProcessStreamConnect (char * buf, size_t len);
|
||||
@@ -120,7 +123,7 @@ namespace client
|
||||
struct SAMSession
|
||||
{
|
||||
ClientDestination * localDestination;
|
||||
std::list<SAMSocket *> sockets;
|
||||
std::list<std::shared_ptr<SAMSocket> > sockets;
|
||||
};
|
||||
|
||||
class SAMBridge
|
||||
@@ -143,7 +146,7 @@ namespace client
|
||||
void Run ();
|
||||
|
||||
void Accept ();
|
||||
void HandleAccept(const boost::system::error_code& ecode);
|
||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<SAMSocket> socket);
|
||||
|
||||
void ReceiveDatagram ();
|
||||
void HandleReceivedDatagram (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
@@ -156,7 +159,6 @@ namespace client
|
||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||
boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint;
|
||||
boost::asio::ip::udp::socket m_DatagramSocket;
|
||||
SAMSocket * m_NewSocket;
|
||||
std::mutex m_SessionsMutex;
|
||||
std::map<std::string, SAMSession> m_Sessions;
|
||||
uint8_t m_DatagramReceiveBuffer[i2p::datagram::MAX_DATAGRAM_SIZE+1];
|
||||
|
||||
132
SSU.h
132
SSU.h
@@ -13,137 +13,16 @@
|
||||
#include "Identity.h"
|
||||
#include "RouterInfo.h"
|
||||
#include "I2NPProtocol.h"
|
||||
#include "TransportSession.h"
|
||||
#include "SSUData.h"
|
||||
#include "SSUSession.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace transport
|
||||
{
|
||||
#pragma pack(1)
|
||||
struct SSUHeader
|
||||
{
|
||||
uint8_t mac[16];
|
||||
uint8_t iv[16];
|
||||
uint8_t flag;
|
||||
uint32_t time;
|
||||
|
||||
uint8_t GetPayloadType () const { return flag >> 4; };
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds
|
||||
const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes
|
||||
const int SSU_KEEP_ALIVE_INTERVAL = 30; // 30 seconds
|
||||
const int SSU_TO_INTRODUCER_SESSION_DURATION = 3600; // 1 hour
|
||||
const size_t SSU_MAX_NUM_INTRODUCERS = 3;
|
||||
|
||||
// payload types (4 bits)
|
||||
const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0;
|
||||
const uint8_t PAYLOAD_TYPE_SESSION_CREATED = 1;
|
||||
const uint8_t PAYLOAD_TYPE_SESSION_CONFIRMED = 2;
|
||||
const uint8_t PAYLOAD_TYPE_RELAY_REQUEST = 3;
|
||||
const uint8_t PAYLOAD_TYPE_RELAY_RESPONSE = 4;
|
||||
const uint8_t PAYLOAD_TYPE_RELAY_INTRO = 5;
|
||||
const uint8_t PAYLOAD_TYPE_DATA = 6;
|
||||
const uint8_t PAYLOAD_TYPE_PEER_TEST = 7;
|
||||
const uint8_t PAYLOAD_TYPE_SESSION_DESTROYED = 8;
|
||||
|
||||
enum SessionState
|
||||
{
|
||||
eSessionStateUnknown,
|
||||
eSessionStateIntroduced,
|
||||
eSessionStateEstablished,
|
||||
eSessionStateFailed
|
||||
};
|
||||
|
||||
class SSUServer;
|
||||
class SSUSession: public TransportSession
|
||||
{
|
||||
public:
|
||||
|
||||
SSUSession (SSUServer& server, boost::asio::ip::udp::endpoint& remoteEndpoint,
|
||||
const i2p::data::RouterInfo * router = nullptr, bool peerTest = false);
|
||||
void ProcessNextMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
|
||||
~SSUSession ();
|
||||
|
||||
void Connect ();
|
||||
void Introduce (uint32_t iTag, const uint8_t * iKey);
|
||||
void WaitForIntroduction ();
|
||||
void Close ();
|
||||
boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; };
|
||||
bool IsV6 () const { return m_RemoteEndpoint.address ().is_v6 (); };
|
||||
void SendI2NPMessage (I2NPMessage * msg);
|
||||
void SendPeerTest (); // Alice
|
||||
|
||||
SessionState GetState () const { return m_State; };
|
||||
size_t GetNumSentBytes () const { return m_NumSentBytes; };
|
||||
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
||||
|
||||
void SendKeepAlive ();
|
||||
uint32_t GetRelayTag () const { return m_RelayTag; };
|
||||
uint32_t GetCreationTime () const { return m_CreationTime; };
|
||||
|
||||
private:
|
||||
|
||||
void CreateAESandMacKey (const uint8_t * pubKey);
|
||||
|
||||
void PostI2NPMessage (I2NPMessage * msg);
|
||||
void ProcessMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); // call for established session
|
||||
void ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
|
||||
void SendSessionRequest ();
|
||||
void SendRelayRequest (uint32_t iTag, const uint8_t * iKey);
|
||||
void ProcessSessionCreated (uint8_t * buf, size_t len);
|
||||
void SendSessionCreated (const uint8_t * x);
|
||||
void ProcessSessionConfirmed (uint8_t * buf, size_t len);
|
||||
void SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, size_t ourAddressLen);
|
||||
void ProcessRelayRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from);
|
||||
void SendRelayResponse (uint32_t nonce, const boost::asio::ip::udp::endpoint& from,
|
||||
const uint8_t * introKey, const boost::asio::ip::udp::endpoint& to);
|
||||
void SendRelayIntro (SSUSession * session, const boost::asio::ip::udp::endpoint& from);
|
||||
void ProcessRelayResponse (uint8_t * buf, size_t len);
|
||||
void ProcessRelayIntro (uint8_t * buf, size_t len);
|
||||
void Established ();
|
||||
void Failed ();
|
||||
void ScheduleConnectTimer ();
|
||||
void HandleConnectTimer (const boost::system::error_code& ecode);
|
||||
void ProcessPeerTest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
|
||||
void SendPeerTest (uint32_t nonce, uint32_t address, uint16_t port, const uint8_t * introKey, bool toAddress = true);
|
||||
void ProcessData (uint8_t * buf, size_t len);
|
||||
void SendSesionDestroyed ();
|
||||
void Send (uint8_t type, const uint8_t * payload, size_t len); // with session key
|
||||
void Send (const uint8_t * buf, size_t size);
|
||||
|
||||
void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const uint8_t * aesKey, const uint8_t * iv, const uint8_t * macKey);
|
||||
void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len); // with session key
|
||||
void Decrypt (uint8_t * buf, size_t len, const uint8_t * aesKey);
|
||||
void DecryptSessionKey (uint8_t * buf, size_t len);
|
||||
bool Validate (uint8_t * buf, size_t len, const uint8_t * macKey);
|
||||
const uint8_t * GetIntroKey () const;
|
||||
|
||||
void ScheduleTermination ();
|
||||
void HandleTerminationTimer (const boost::system::error_code& ecode);
|
||||
|
||||
private:
|
||||
|
||||
friend class SSUData; // TODO: change in later
|
||||
SSUServer& m_Server;
|
||||
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
|
||||
boost::asio::deadline_timer m_Timer;
|
||||
bool m_PeerTest;
|
||||
SessionState m_State;
|
||||
bool m_IsSessionKey;
|
||||
uint32_t m_RelayTag;
|
||||
std::set<uint32_t> m_PeerTestNonces;
|
||||
i2p::crypto::CBCEncryption m_SessionKeyEncryption;
|
||||
i2p::crypto::CBCDecryption m_SessionKeyDecryption;
|
||||
uint8_t m_SessionKey[32], m_MacKey[32];
|
||||
std::list<i2p::I2NPMessage *> m_DelayedMessages;
|
||||
SSUData m_Data;
|
||||
size_t m_NumSentBytes, m_NumReceivedBytes;
|
||||
uint32_t m_CreationTime; // seconds since epoch
|
||||
};
|
||||
|
||||
class SSUServer
|
||||
{
|
||||
public:
|
||||
@@ -152,9 +31,9 @@ namespace transport
|
||||
~SSUServer ();
|
||||
void Start ();
|
||||
void Stop ();
|
||||
SSUSession * GetSession (const i2p::data::RouterInfo * router, bool peerTest = false);
|
||||
SSUSession * FindSession (const i2p::data::RouterInfo * router);
|
||||
SSUSession * FindSession (const boost::asio::ip::udp::endpoint& e);
|
||||
SSUSession * GetSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false);
|
||||
SSUSession * FindSession (const i2p::data::RouterInfo * router) const;
|
||||
SSUSession * FindSession (const boost::asio::ip::udp::endpoint& e) const;
|
||||
SSUSession * GetRandomEstablishedSession (const SSUSession * excluded);
|
||||
void DeleteSession (SSUSession * session);
|
||||
void DeleteAllSessions ();
|
||||
@@ -192,7 +71,8 @@ namespace transport
|
||||
boost::asio::ip::udp::endpoint m_SenderEndpoint, m_SenderEndpointV6;
|
||||
boost::asio::deadline_timer m_IntroducersUpdateTimer;
|
||||
std::list<boost::asio::ip::udp::endpoint> m_Introducers; // introducers we are connected to
|
||||
uint8_t m_ReceiveBuffer[2*SSU_MTU_V4], m_ReceiveBufferV6[2*SSU_MTU_V6];
|
||||
i2p::crypto::AESAlignedBuffer<2*SSU_MTU_V4> m_ReceiveBuffer;
|
||||
i2p::crypto::AESAlignedBuffer<2*SSU_MTU_V6> m_ReceiveBufferV6;
|
||||
std::map<boost::asio::ip::udp::endpoint, SSUSession *> m_Sessions;
|
||||
std::map<uint32_t, boost::asio::ip::udp::endpoint> m_Relays; // we are introducer
|
||||
|
||||
|
||||
@@ -148,6 +148,11 @@ namespace transport
|
||||
bool isLast = fragmentInfo & 0x010000; // bit 16
|
||||
uint8_t fragmentNum = fragmentInfo >> 17; // bits 23 - 17
|
||||
LogPrint (eLogDebug, "SSU data fragment ", (int)fragmentNum, " of message ", msgID, " size=", (int)fragmentSize, isLast ? " last" : " non-last");
|
||||
if (fragmentSize >= SSU_V4_MAX_PACKET_SIZE)
|
||||
{
|
||||
LogPrint (eLogError, "Fragment size ", fragmentSize, "exceeds max SSU packet size");
|
||||
return;
|
||||
}
|
||||
|
||||
// find message with msgID
|
||||
I2NPMessage * msg = nullptr;
|
||||
|
||||
1012
SSUSession.cpp
Normal file
1012
SSUSession.cpp
Normal file
File diff suppressed because it is too large
Load Diff
145
SSUSession.h
Normal file
145
SSUSession.h
Normal file
@@ -0,0 +1,145 @@
|
||||
#ifndef SSU_SESSION_H__
|
||||
#define SSU_SESSION_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <boost/asio.hpp>
|
||||
#include "aes.h"
|
||||
#include "hmac.h"
|
||||
#include "I2NPProtocol.h"
|
||||
#include "TransportSession.h"
|
||||
#include "SSUData.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace transport
|
||||
{
|
||||
#pragma pack(1)
|
||||
struct SSUHeader
|
||||
{
|
||||
uint8_t mac[16];
|
||||
uint8_t iv[16];
|
||||
uint8_t flag;
|
||||
uint32_t time;
|
||||
|
||||
uint8_t GetPayloadType () const { return flag >> 4; };
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds
|
||||
const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes
|
||||
|
||||
// payload types (4 bits)
|
||||
const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0;
|
||||
const uint8_t PAYLOAD_TYPE_SESSION_CREATED = 1;
|
||||
const uint8_t PAYLOAD_TYPE_SESSION_CONFIRMED = 2;
|
||||
const uint8_t PAYLOAD_TYPE_RELAY_REQUEST = 3;
|
||||
const uint8_t PAYLOAD_TYPE_RELAY_RESPONSE = 4;
|
||||
const uint8_t PAYLOAD_TYPE_RELAY_INTRO = 5;
|
||||
const uint8_t PAYLOAD_TYPE_DATA = 6;
|
||||
const uint8_t PAYLOAD_TYPE_PEER_TEST = 7;
|
||||
const uint8_t PAYLOAD_TYPE_SESSION_DESTROYED = 8;
|
||||
|
||||
enum SessionState
|
||||
{
|
||||
eSessionStateUnknown,
|
||||
eSessionStateIntroduced,
|
||||
eSessionStateEstablished,
|
||||
eSessionStateFailed
|
||||
};
|
||||
|
||||
class SSUServer;
|
||||
class SSUSession: public TransportSession
|
||||
{
|
||||
public:
|
||||
|
||||
SSUSession (SSUServer& server, boost::asio::ip::udp::endpoint& remoteEndpoint,
|
||||
std::shared_ptr<const i2p::data::RouterInfo> router = nullptr, bool peerTest = false);
|
||||
void ProcessNextMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
|
||||
~SSUSession ();
|
||||
|
||||
void Connect ();
|
||||
void Introduce (uint32_t iTag, const uint8_t * iKey);
|
||||
void WaitForIntroduction ();
|
||||
void Close ();
|
||||
boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; };
|
||||
bool IsV6 () const { return m_RemoteEndpoint.address ().is_v6 (); };
|
||||
void SendI2NPMessage (I2NPMessage * msg);
|
||||
void SendPeerTest (); // Alice
|
||||
|
||||
SessionState GetState () const { return m_State; };
|
||||
size_t GetNumSentBytes () const { return m_NumSentBytes; };
|
||||
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
||||
|
||||
void SendKeepAlive ();
|
||||
uint32_t GetRelayTag () const { return m_RelayTag; };
|
||||
uint32_t GetCreationTime () const { return m_CreationTime; };
|
||||
|
||||
private:
|
||||
|
||||
void CreateAESandMacKey (const uint8_t * pubKey);
|
||||
|
||||
void PostI2NPMessage (I2NPMessage * msg);
|
||||
void ProcessMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); // call for established session
|
||||
void ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
|
||||
void SendSessionRequest ();
|
||||
void SendRelayRequest (uint32_t iTag, const uint8_t * iKey);
|
||||
void ProcessSessionCreated (uint8_t * buf, size_t len);
|
||||
void SendSessionCreated (const uint8_t * x);
|
||||
void ProcessSessionConfirmed (uint8_t * buf, size_t len);
|
||||
void SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, size_t ourAddressLen);
|
||||
void ProcessRelayRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from);
|
||||
void SendRelayResponse (uint32_t nonce, const boost::asio::ip::udp::endpoint& from,
|
||||
const uint8_t * introKey, const boost::asio::ip::udp::endpoint& to);
|
||||
void SendRelayIntro (SSUSession * session, const boost::asio::ip::udp::endpoint& from);
|
||||
void ProcessRelayResponse (uint8_t * buf, size_t len);
|
||||
void ProcessRelayIntro (uint8_t * buf, size_t len);
|
||||
void Established ();
|
||||
void Failed ();
|
||||
void ScheduleConnectTimer ();
|
||||
void HandleConnectTimer (const boost::system::error_code& ecode);
|
||||
void ProcessPeerTest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
|
||||
void SendPeerTest (uint32_t nonce, uint32_t address, uint16_t port, const uint8_t * introKey, bool toAddress = true);
|
||||
void ProcessData (uint8_t * buf, size_t len);
|
||||
void SendSesionDestroyed ();
|
||||
void Send (uint8_t type, const uint8_t * payload, size_t len); // with session key
|
||||
void Send (const uint8_t * buf, size_t size);
|
||||
|
||||
void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const uint8_t * aesKey, const uint8_t * iv, const uint8_t * macKey);
|
||||
void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len); // with session key
|
||||
void Decrypt (uint8_t * buf, size_t len, const uint8_t * aesKey);
|
||||
void DecryptSessionKey (uint8_t * buf, size_t len);
|
||||
bool Validate (uint8_t * buf, size_t len, const uint8_t * macKey);
|
||||
const uint8_t * GetIntroKey () const;
|
||||
|
||||
void ScheduleTermination ();
|
||||
void HandleTerminationTimer (const boost::system::error_code& ecode);
|
||||
|
||||
private:
|
||||
|
||||
friend class SSUData; // TODO: change in later
|
||||
SSUServer& m_Server;
|
||||
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
|
||||
boost::asio::deadline_timer m_Timer;
|
||||
bool m_PeerTest;
|
||||
SessionState m_State;
|
||||
bool m_IsSessionKey;
|
||||
uint32_t m_RelayTag;
|
||||
std::set<uint32_t> m_PeerTestNonces;
|
||||
i2p::crypto::CBCEncryption m_SessionKeyEncryption;
|
||||
i2p::crypto::CBCDecryption m_SessionKeyDecryption;
|
||||
i2p::crypto::AESKey m_SessionKey;
|
||||
i2p::crypto::MACKey m_MacKey;
|
||||
std::list<i2p::I2NPMessage *> m_DelayedMessages;
|
||||
SSUData m_Data;
|
||||
size_t m_NumSentBytes, m_NumReceivedBytes;
|
||||
uint32_t m_CreationTime; // seconds since epoch
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -153,6 +153,8 @@ namespace stream
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::function<void (Stream *)> Acceptor;
|
||||
|
||||
StreamingDestination (i2p::client::ClientDestination& owner): m_Owner (owner) {};
|
||||
~StreamingDestination () {};
|
||||
|
||||
@@ -161,7 +163,7 @@ namespace stream
|
||||
|
||||
Stream * CreateNewOutgoingStream (const i2p::data::LeaseSet& remote, int port = 0);
|
||||
void DeleteStream (Stream * stream);
|
||||
void SetAcceptor (const std::function<void (Stream *)>& acceptor) { m_Acceptor = acceptor; };
|
||||
void SetAcceptor (const Acceptor& acceptor) { m_Acceptor = acceptor; };
|
||||
void ResetAcceptor () { m_Acceptor = nullptr; };
|
||||
bool IsAcceptorSet () const { return m_Acceptor != nullptr; };
|
||||
i2p::client::ClientDestination& GetOwner () { return m_Owner; };
|
||||
@@ -178,7 +180,7 @@ namespace stream
|
||||
i2p::client::ClientDestination& m_Owner;
|
||||
std::mutex m_StreamsMutex;
|
||||
std::map<uint32_t, Stream *> m_Streams;
|
||||
std::function<void (Stream *)> m_Acceptor;
|
||||
Acceptor m_Acceptor;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include "Identity.h"
|
||||
#include "RouterInfo.h"
|
||||
|
||||
@@ -51,7 +52,7 @@ namespace transport
|
||||
{
|
||||
public:
|
||||
|
||||
TransportSession (const i2p::data::RouterInfo * in_RemoteRouter):
|
||||
TransportSession (std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter):
|
||||
m_RemoteRouter (in_RemoteRouter), m_DHKeysPair (nullptr)
|
||||
{
|
||||
if (m_RemoteRouter)
|
||||
@@ -60,12 +61,12 @@ namespace transport
|
||||
|
||||
virtual ~TransportSession () { delete m_DHKeysPair; };
|
||||
|
||||
const i2p::data::RouterInfo * GetRemoteRouter () { return m_RemoteRouter; };
|
||||
std::shared_ptr<const i2p::data::RouterInfo> GetRemoteRouter () { return m_RemoteRouter; };
|
||||
const i2p::data::IdentityEx& GetRemoteIdentity () { return m_RemoteIdentity; };
|
||||
|
||||
protected:
|
||||
|
||||
const i2p::data::RouterInfo * m_RemoteRouter;
|
||||
std::shared_ptr<const i2p::data::RouterInfo> m_RemoteRouter;
|
||||
i2p::data::IdentityEx m_RemoteIdentity;
|
||||
DHKeysPair * m_DHKeysPair; // X - for client and Y - for server
|
||||
};
|
||||
|
||||
@@ -277,10 +277,10 @@ namespace transport
|
||||
session->SendI2NPMessage (msg);
|
||||
else
|
||||
{
|
||||
RouterInfo * r = netdb.FindRouter (ident);
|
||||
auto r = netdb.FindRouter (ident);
|
||||
if (r)
|
||||
{
|
||||
auto ssuSession = m_SSUServer ? m_SSUServer->FindSession (r) : nullptr;
|
||||
auto ssuSession = m_SSUServer ? m_SSUServer->FindSession (r.get ()) : nullptr;
|
||||
if (ssuSession)
|
||||
ssuSession->SendI2NPMessage (msg);
|
||||
else
|
||||
@@ -290,7 +290,7 @@ namespace transport
|
||||
auto address = r->GetNTCPAddress (!context.SupportsV6 ());
|
||||
if (address && !r->UsesIntroducer () && !r->IsUnreachable () && msg->GetLength () < NTCP_MAX_MESSAGE_SIZE)
|
||||
{
|
||||
auto s = new NTCPClient (m_Service, address->host, address->port, *r);
|
||||
auto s = new NTCPClient (m_Service, address->host, address->port, r);
|
||||
AddNTCPSession (s);
|
||||
s->SendI2NPMessage (msg);
|
||||
}
|
||||
@@ -323,7 +323,7 @@ namespace transport
|
||||
void Transports::HandleResendTimer (const boost::system::error_code& ecode,
|
||||
boost::asio::deadline_timer * timer, const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg)
|
||||
{
|
||||
RouterInfo * r = netdb.FindRouter (ident);
|
||||
auto r = netdb.FindRouter (ident);
|
||||
if (r)
|
||||
{
|
||||
LogPrint ("Router found. Sending message");
|
||||
|
||||
@@ -466,7 +466,7 @@ namespace tunnel
|
||||
if (!inboundTunnel) return;
|
||||
LogPrint ("Creating one hop outbound tunnel...");
|
||||
CreateTunnel<OutboundTunnel> (
|
||||
new TunnelConfig (std::vector<const i2p::data::RouterInfo *>
|
||||
new TunnelConfig (std::vector<std::shared_ptr<const i2p::data::RouterInfo> >
|
||||
{
|
||||
i2p::data::netdb.GetRandomRouter ()
|
||||
},
|
||||
@@ -519,7 +519,7 @@ namespace tunnel
|
||||
// trying to create one more inbound tunnel
|
||||
LogPrint ("Creating one hop inbound tunnel...");
|
||||
CreateTunnel<InboundTunnel> (
|
||||
new TunnelConfig (std::vector<const i2p::data::RouterInfo *>
|
||||
new TunnelConfig (std::vector<std::shared_ptr<const i2p::data::RouterInfo> >
|
||||
{
|
||||
i2p::data::netdb.GetRandomRouter ()
|
||||
}));
|
||||
@@ -609,9 +609,9 @@ namespace tunnel
|
||||
void Tunnels::CreateZeroHopsInboundTunnel ()
|
||||
{
|
||||
CreateTunnel<InboundTunnel> (
|
||||
new TunnelConfig (std::vector<const i2p::data::RouterInfo *>
|
||||
new TunnelConfig (std::vector<std::shared_ptr<const i2p::data::RouterInfo> >
|
||||
{
|
||||
&i2p::context.GetRouterInfo ()
|
||||
i2p::context.GetSharedRouterInfo ()
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
2
Tunnel.h
2
Tunnel.h
@@ -79,7 +79,7 @@ namespace tunnel
|
||||
|
||||
void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg);
|
||||
void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
|
||||
const i2p::data::RouterInfo * GetEndpointRouter () const
|
||||
std::shared_ptr<const i2p::data::RouterInfo> GetEndpointRouter () const
|
||||
{ return GetTunnelConfig ()->GetLastHop ()->router; };
|
||||
size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "aes.h"
|
||||
#include "RouterInfo.h"
|
||||
#include "RouterContext.h"
|
||||
@@ -14,7 +15,7 @@ namespace tunnel
|
||||
{
|
||||
struct TunnelHopConfig
|
||||
{
|
||||
const i2p::data::RouterInfo * router, * nextRouter;
|
||||
std::shared_ptr<const i2p::data::RouterInfo> router, nextRouter;
|
||||
uint32_t tunnelID, nextTunnelID;
|
||||
uint8_t layerKey[32];
|
||||
uint8_t ivKey[32];
|
||||
@@ -26,7 +27,7 @@ namespace tunnel
|
||||
i2p::crypto::TunnelDecryption decryption;
|
||||
int recordIndex; // record # in tunnel build message
|
||||
|
||||
TunnelHopConfig (const i2p::data::RouterInfo * r)
|
||||
TunnelHopConfig (std::shared_ptr<const i2p::data::RouterInfo> r)
|
||||
{
|
||||
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
||||
rnd.GenerateBlock (layerKey, 32);
|
||||
@@ -36,14 +37,14 @@ namespace tunnel
|
||||
isGateway = true;
|
||||
isEndpoint = true;
|
||||
router = r;
|
||||
nextRouter = 0;
|
||||
//nextRouter = nullptr;
|
||||
nextTunnelID = 0;
|
||||
|
||||
next = 0;
|
||||
prev = 0;
|
||||
next = nullptr;
|
||||
prev = nullptr;
|
||||
}
|
||||
|
||||
void SetNextRouter (const i2p::data::RouterInfo * r)
|
||||
void SetNextRouter (std::shared_ptr<const i2p::data::RouterInfo> r)
|
||||
{
|
||||
nextRouter = r;
|
||||
isEndpoint = false;
|
||||
@@ -88,7 +89,7 @@ namespace tunnel
|
||||
public:
|
||||
|
||||
|
||||
TunnelConfig (std::vector<const i2p::data::RouterInfo *> peers,
|
||||
TunnelConfig (std::vector<std::shared_ptr<const i2p::data::RouterInfo> > peers,
|
||||
const TunnelConfig * replyTunnelConfig = nullptr) // replyTunnelConfig=nullptr means inbound
|
||||
{
|
||||
TunnelHopConfig * prev = nullptr;
|
||||
@@ -109,7 +110,7 @@ namespace tunnel
|
||||
m_LastHop->SetReplyHop (replyTunnelConfig->GetFirstHop ());
|
||||
}
|
||||
else // inbound
|
||||
m_LastHop->SetNextRouter (&i2p::context.GetRouterInfo ());
|
||||
m_LastHop->SetNextRouter (i2p::context.GetSharedRouterInfo ());
|
||||
}
|
||||
|
||||
~TunnelConfig ()
|
||||
@@ -184,7 +185,7 @@ namespace tunnel
|
||||
if (hop->isGateway) // inbound tunnel
|
||||
newHop->SetReplyHop (m_FirstHop); // use it as reply tunnel
|
||||
else
|
||||
newHop->SetNextRouter (&i2p::context.GetRouterInfo ());
|
||||
newHop->SetNextRouter (i2p::context.GetSharedRouterInfo ());
|
||||
}
|
||||
if (!hop->next) newConfig->m_FirstHop = newHop; // last hop
|
||||
|
||||
@@ -195,7 +196,7 @@ namespace tunnel
|
||||
|
||||
TunnelConfig * Clone (const TunnelConfig * replyTunnelConfig = nullptr) const
|
||||
{
|
||||
std::vector<const i2p::data::RouterInfo *> peers;
|
||||
std::vector<std::shared_ptr<const i2p::data::RouterInfo> > peers;
|
||||
TunnelHopConfig * hop = m_FirstHop;
|
||||
while (hop)
|
||||
{
|
||||
|
||||
@@ -235,7 +235,7 @@ namespace tunnel
|
||||
m_LocalDestination.ProcessDeliveryStatusMessage (msg);
|
||||
}
|
||||
|
||||
const i2p::data::RouterInfo * TunnelPool::SelectNextHop (const i2p::data::RouterInfo * prevHop) const
|
||||
std::shared_ptr<const i2p::data::RouterInfo> TunnelPool::SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const
|
||||
{
|
||||
auto hop = m_NumHops >= 3 ? i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop) :
|
||||
i2p::data::netdb.GetRandomRouter (prevHop);
|
||||
@@ -250,8 +250,8 @@ namespace tunnel
|
||||
if (!outboundTunnel)
|
||||
outboundTunnel = tunnels.GetNextOutboundTunnel ();
|
||||
LogPrint ("Creating destination inbound tunnel...");
|
||||
const i2p::data::RouterInfo * prevHop = &i2p::context.GetRouterInfo ();
|
||||
std::vector<const i2p::data::RouterInfo *> hops;
|
||||
auto prevHop = i2p::context.GetSharedRouterInfo ();
|
||||
std::vector<std::shared_ptr<const i2p::data::RouterInfo> > hops;
|
||||
int numHops = m_NumHops;
|
||||
if (outboundTunnel)
|
||||
{
|
||||
@@ -294,8 +294,8 @@ namespace tunnel
|
||||
{
|
||||
LogPrint ("Creating destination outbound tunnel...");
|
||||
|
||||
const i2p::data::RouterInfo * prevHop = &i2p::context.GetRouterInfo ();
|
||||
std::vector<const i2p::data::RouterInfo *> hops;
|
||||
auto prevHop = i2p::context.GetSharedRouterInfo ();
|
||||
std::vector<std::shared_ptr<const i2p::data::RouterInfo> > hops;
|
||||
for (int i = 0; i < m_NumHops; i++)
|
||||
{
|
||||
auto hop = SelectNextHop (prevHop);
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace tunnel
|
||||
template<class TTunnels>
|
||||
typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels,
|
||||
typename TTunnels::value_type suggested = nullptr) const;
|
||||
const i2p::data::RouterInfo * SelectNextHop (const i2p::data::RouterInfo * prevHop) const;
|
||||
std::shared_ptr<const i2p::data::RouterInfo> SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
282
Win32/PurpleI2P.nsi
Normal file
282
Win32/PurpleI2P.nsi
Normal file
@@ -0,0 +1,282 @@
|
||||
# NSIS Installer script. (Tested with NSIS 2.64 on Windows 7)
|
||||
# Author: Mikal Villa (Meeh)
|
||||
# Version: 1.1
|
||||
Name PurpleI2P
|
||||
|
||||
RequestExecutionLevel highest
|
||||
SetCompressor /SOLID lzma
|
||||
ShowInstDetails show
|
||||
|
||||
# General Symbol Definitions
|
||||
!define REGKEY "SOFTWARE\$(^Name)"
|
||||
!define VERSION 0.3.0.0
|
||||
!define COMPANY "The Privacy Solutions Project"
|
||||
!define URL "https://i2p.io"
|
||||
|
||||
# MUI Symbol Definitions
|
||||
!define MUI_ICON "ictoopie.ico"
|
||||
#!define MUI_WELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp"
|
||||
!define MUI_HEADERIMAGE
|
||||
!define MUI_HEADERIMAGE_RIGHT
|
||||
#!define MUI_HEADERIMAGE_BITMAP "../share/pixmaps/nsis-header.bmp"
|
||||
!define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY}
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup
|
||||
!define MUI_STARTMENUPAGE_DEFAULTFOLDER PurpleI2P
|
||||
!define MUI_FINISHPAGE_RUN $INSTDIR\i2pd.exe
|
||||
!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\Readme.txt
|
||||
|
||||
|
||||
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
|
||||
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp"
|
||||
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
|
||||
|
||||
# Included files
|
||||
!include Sections.nsh
|
||||
!include MUI2.nsh
|
||||
!include nsDialogs.nsh
|
||||
!include winmessages.nsh
|
||||
!include logiclib.nsh
|
||||
# Local included files
|
||||
!include nsi\helper_readme.nsh
|
||||
;!include nsi\servicelib.nsh
|
||||
|
||||
# Variables
|
||||
Var StartMenuGroup
|
||||
|
||||
# Installer pages
|
||||
# Execution flow of installer windows
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_README "../Readme.md"
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
# Disabled for now. Use the bat
|
||||
;Page custom mode_selection # Meeh's hack for installing and starting service.
|
||||
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
# Uninstall pages
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
# Installer languages
|
||||
!insertmacro MUI_LANGUAGE English
|
||||
|
||||
# Installer attributes
|
||||
OutFile PurpleI2P-0.3.0.0-win32-setup.exe
|
||||
InstallDir $PROGRAMFILES\PurpleI2P
|
||||
CRCCheck on
|
||||
XPStyle on
|
||||
BrandingText " "
|
||||
ShowInstDetails show
|
||||
VIProductVersion 0.3.0.0
|
||||
VIAddVersionKey ProductName PurpleI2P
|
||||
VIAddVersionKey ProductVersion "${VERSION}"
|
||||
VIAddVersionKey CompanyName "${COMPANY}"
|
||||
VIAddVersionKey CompanyWebsite "${URL}"
|
||||
VIAddVersionKey FileVersion "${VERSION}"
|
||||
VIAddVersionKey FileDescription ""
|
||||
VIAddVersionKey LegalCopyright ""
|
||||
InstallDirRegKey HKCU "${REGKEY}" Path
|
||||
ShowUninstDetails show
|
||||
|
||||
# Readme definitions
|
||||
|
||||
;--------------------------------
|
||||
;Languages
|
||||
;Set up install lang strings for 1st lang
|
||||
${ReadmeLanguage} "${LANG_ENGLISH}" \
|
||||
"Read Me" \
|
||||
"Please review the following important information." \
|
||||
"About $(^name):" \
|
||||
"$\n Click on scrollbar arrows or press Page Down to review the entire text."
|
||||
|
||||
;Add 2nd language
|
||||
!insertmacro MUI_LANGUAGE "Norwegian"
|
||||
|
||||
;set up install lang strings for second lang
|
||||
${ReadmeLanguage} "${LANG_NORWEGIAN}" \
|
||||
"Les meg!" \
|
||||
"Vennligst les informasjonen om hvordan du skal bruke PurpleI2P." \
|
||||
"Om $(^name):" \
|
||||
"$\n Klikk på scrollbaren til høyre for å se hele innholdet."
|
||||
|
||||
;--------------------------------
|
||||
|
||||
# Installer sections
|
||||
Section -Main SEC0000
|
||||
SetOutPath $INSTDIR
|
||||
SetOverwrite on
|
||||
File /oname=i2pd.exe Release\i2pd.exe
|
||||
File /oname=install_service.bat install_service.bat
|
||||
File /oname=uninstall_service.bat uninstall_service.bat
|
||||
File /oname=LICENSE.txt ..\LICENSE
|
||||
File /oname=Readme.txt ..\README.md
|
||||
SetOutPath $INSTDIR\src
|
||||
File /r /x *.nsi /x *.rc /x *.exe /x *.obj /x *.nsh /x *.sln /x *.vcxproj /x *.tlog /x *.log /x *.res /x *.pdb /x *.suo /x *.opensdf /x *.filters /x *.sdf /x *.iss /x *.aps /x .gitignore /x *.o ../\*.*
|
||||
SetOutPath $INSTDIR
|
||||
RMDir /r /REBOOTOK $INSTDIR\src\.git # Remove git directory
|
||||
RMDir /r /REBOOTOK $INSTDIR\src\Win32\Release # Removing release directory
|
||||
RMDir /r /REBOOTOK $INSTDIR\src\Win32\nsi
|
||||
WriteRegStr HKCU "${REGKEY}\Components" Main 1
|
||||
SectionEnd
|
||||
|
||||
Section -post SEC0001
|
||||
WriteRegStr HKCU "${REGKEY}" Path $INSTDIR
|
||||
SetOutPath $INSTDIR
|
||||
WriteUninstaller $INSTDIR\uninstall.exe
|
||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
||||
CreateDirectory $SMPROGRAMS\$StartMenuGroup
|
||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\PurpleI2P.lnk" $INSTDIR\i2pd.exe
|
||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Install PurpleI2P Service.lnk" $INSTDIR\install_service.bat
|
||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P Service.lnk" $INSTDIR\uninstall_service.bat
|
||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P.lnk" $INSTDIR\uninstall.exe
|
||||
!insertmacro MUI_STARTMENU_WRITE_END
|
||||
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)"
|
||||
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}"
|
||||
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}"
|
||||
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}"
|
||||
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe
|
||||
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe
|
||||
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
|
||||
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
|
||||
WriteRegStr HKCR "i2pd" "URL Protocol" ""
|
||||
WriteRegStr HKCR "i2pd" "" "URL:i2pd" # TODO: if a instance of own is found, relaunch with a proxyfied browser to open webage. (e.g i2pd://meeh.i2p)
|
||||
WriteRegStr HKCR "i2pd\DefaultIcon" "" $INSTDIR\i2pd.exe
|
||||
WriteRegStr HKCR "i2pd\shell\open\command" "" '"$INSTDIR\i2pd.exe" "%1"'
|
||||
SectionEnd
|
||||
|
||||
# Macro for selecting uninstaller sections
|
||||
!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID
|
||||
Push $R0
|
||||
ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}"
|
||||
StrCmp $R0 1 0 next${UNSECTION_ID}
|
||||
!insertmacro SelectSection "${UNSECTION_ID}"
|
||||
GoTo done${UNSECTION_ID}
|
||||
next${UNSECTION_ID}:
|
||||
!insertmacro UnselectSection "${UNSECTION_ID}"
|
||||
done${UNSECTION_ID}:
|
||||
Pop $R0
|
||||
!macroend
|
||||
|
||||
|
||||
# Uninstaller sections
|
||||
Section /o -un.Main UNSEC0000
|
||||
Delete /REBOOTOK $INSTDIR\i2pd.exe
|
||||
Delete /REBOOTOK $INSTDIR\LICENSE.txt
|
||||
Delete /REBOOTOK $INSTDIR\Readme.txt
|
||||
Delete /REBOOTOK $INSTDIR\install_service.bat
|
||||
Delete /REBOOTOK $INSTDIR\uninstall_service.bat
|
||||
RMDir /r /REBOOTOK $INSTDIR\src
|
||||
DeleteRegValue HKCU "${REGKEY}\Components" Main
|
||||
SectionEnd
|
||||
|
||||
Section -un.post UNSEC0001
|
||||
DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)"
|
||||
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P.lnk"
|
||||
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\PurpleI2P.lnk"
|
||||
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Install PurpleI2P Service.lnk"
|
||||
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\UnInstall PurpleI2P Service.lnk"
|
||||
Delete /REBOOTOK "$SMSTARTUP\PurpleI2P.lnk"
|
||||
Delete /REBOOTOK $INSTDIR\uninstall.exe
|
||||
Delete /REBOOTOK $INSTDIR\debug.log
|
||||
DeleteRegValue HKCU "${REGKEY}" StartMenuGroup
|
||||
DeleteRegValue HKCU "${REGKEY}" Path
|
||||
DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components"
|
||||
DeleteRegKey /IfEmpty HKCU "${REGKEY}"
|
||||
DeleteRegKey HKCR "i2pd"
|
||||
RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup
|
||||
RmDir /REBOOTOK $INSTDIR
|
||||
Push $R0
|
||||
StrCpy $R0 $StartMenuGroup 1
|
||||
StrCmp $R0 ">" no_smgroup
|
||||
no_smgroup:
|
||||
Pop $R0
|
||||
SectionEnd
|
||||
|
||||
; var hwndExecModeRadio
|
||||
; var hwndRunServiceNowRadio
|
||||
|
||||
; Function mode_selection
|
||||
; nsDialogs::Create 1018
|
||||
; Pop $0
|
||||
; ${NSD_CreateLabel} 0 10 75% 20u "How would you like PurpleI2P (i2pd) to run?"
|
||||
; Pop $0
|
||||
|
||||
; ${NSD_CreateRadioButton} 20 60 80% 25u "Service Mode"
|
||||
; Pop $hwndExecModeRadio
|
||||
; ${NSD_AddStyle} $hwndExecModeRadio ${WS_GROUP}
|
||||
|
||||
; ${NSD_CreateRadioButton} 20 90 80% 25u "Command line Mode"
|
||||
; Pop $0
|
||||
|
||||
; ${NSD_CreateButton} 20 150 -40 14u "Do it!"
|
||||
; Pop $0
|
||||
; ${NSD_OnClick} $0 perform_mode
|
||||
|
||||
; nsDialogs::Show
|
||||
; FunctionEnd
|
||||
|
||||
; Function start_now_selection
|
||||
; nsDialogs::Create 1018
|
||||
; Pop $0
|
||||
; ${NSD_CreateLabel} 0 10 75% 20u "Enable the service now?"
|
||||
; Pop $0
|
||||
|
||||
; ${NSD_CreateRadioButton} 20 60 80% 25u "Yes"
|
||||
; Pop $hwndRunServiceNowRadio
|
||||
; ${NSD_AddStyle} $hwndRunServiceNowRadio ${WS_GROUP}
|
||||
|
||||
; ${NSD_CreateRadioButton} 20 90 80% 25u "No"
|
||||
; Pop $0
|
||||
|
||||
; ${NSD_CreateButton} 20 150 -40 14u "Do it!"
|
||||
; Pop $0
|
||||
; ${NSD_OnClick} $0 perform_mode
|
||||
|
||||
; nsDialogs::Show
|
||||
; FunctionEnd
|
||||
|
||||
; Function perform_mode
|
||||
; ${NSD_GetState} $hwndExecModeRadio $0
|
||||
; ${If} $0 = ${BST_CHECKED}
|
||||
; Call service_mode
|
||||
; ${EndIF}
|
||||
; FunctionEnd
|
||||
|
||||
; Function start_now
|
||||
; ${NSD_GetState} $hwndRunServiceNowRadio $0
|
||||
; ${If} $0 = ${BST_CHECKED}
|
||||
; Call start_now_selection
|
||||
; ${EndIF}
|
||||
; FunctionEnd
|
||||
|
||||
; Function service_mode
|
||||
; Push "create"
|
||||
; Push "PurpleI2P Service"
|
||||
; Push "$INSTDIR\i2pd.exe;autostart=1;display=PurpleI2P"
|
||||
; Call Service
|
||||
; Pop $0 ; Actually more to write than !insertmacro, but much more fun :D
|
||||
; Push "start"
|
||||
; Push "PurpleI2P Service"
|
||||
; Call Service
|
||||
; Pop $0
|
||||
; Call start_now
|
||||
; !define MUI_FINISHPAGE_RUN_NOTCHECKED
|
||||
; !define MUI_FINISHPAGE_RUN_TEXT "No need to run now since we already installed and launched it as a Windows service!"
|
||||
; FunctionEnd
|
||||
|
||||
# Installer functions
|
||||
Function .onInit
|
||||
InitPluginsDir
|
||||
!insertmacro MUI_LANGDLL_DISPLAY
|
||||
FunctionEnd
|
||||
|
||||
# Uninstaller functions
|
||||
Function un.onInit
|
||||
ReadRegStr $INSTDIR HKCU "${REGKEY}" Path
|
||||
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup
|
||||
!insertmacro SELECT_UNSECTION Main ${UNSEC0000}
|
||||
!insertmacro MUI_UNGETLANGUAGE
|
||||
FunctionEnd
|
||||
84
Win32/README-Build.txt
Normal file
84
Win32/README-Build.txt
Normal file
@@ -0,0 +1,84 @@
|
||||
Building i2pd for Windows
|
||||
=========================
|
||||
|
||||
Requirements for building:
|
||||
|
||||
* Visual Studio 2013 (tested with VS2013 Update 1, Update 3, and Update 4 RC)
|
||||
* Boost (tested with 1.56 and 1.57)
|
||||
* Crypto++ (tested with 5.6.2)
|
||||
|
||||
|
||||
Building Boost (32-bit)
|
||||
-----------------------
|
||||
|
||||
Open a Visual Studio x86 command prompt and run the following:
|
||||
|
||||
cd C:\path\to\boost\sources
|
||||
bootstrap
|
||||
b2 toolset=msvc-12.0 --build-type=complete --libdir=C:\Boost\lib\Win32 install --with-filesystem --with-program_options --with-regex --with-date_time
|
||||
|
||||
|
||||
Building Boost (64-bit)
|
||||
-----------------------
|
||||
|
||||
Open a Visual Studio x64 command prompt and run the following:
|
||||
|
||||
cd C:\path\to\boost\sources
|
||||
bootstrap
|
||||
b2 toolset=msvc-12.0 --build-type=complete --libdir=C:\Boost\lib\x64 architecture=x86 address-model=64 install --with-filesystem --with-program_options --with-regex --with-date_time
|
||||
|
||||
After Boost is compiled, set the environment variable `BOOST` to the directory
|
||||
Boost was installed to. If you followed the instructions outlined here, you
|
||||
should set it to `C:\Boost`. Additionally, set the BOOSTVER variable to the
|
||||
version of Boost that you're using, but instead of a '.' use a '_'. For
|
||||
example, I have `BOOSTVER` set to `1_57`.
|
||||
|
||||
Building Crypto++
|
||||
-----------------
|
||||
|
||||
* Open the crypttest Solution in VS2013
|
||||
* Visual Studio will ask to update the Solution/Project. Allow it.
|
||||
* Build the `cryptopp` project, both the Debug and Release targets and for both
|
||||
Win32 and x64.
|
||||
* Create a folder called `cryptopp` in the crypto++ source directory, then copy
|
||||
the header files to this new directory.
|
||||
* Set the `CRYPTOPP` environment variable pointing to the Crypto++ source directory.
|
||||
|
||||
|
||||
Building i2pd
|
||||
-------------
|
||||
|
||||
## Prep work ##
|
||||
|
||||
I strongly advise setting up your own `INCLUDES` and `LIBS` instead of relying
|
||||
on the settings in the i2pd project file. By using your own settings, if the
|
||||
i2pd devs change the paths in the project file, your builds will still work.
|
||||
|
||||
To do this, create or edit the file
|
||||
`%localappdata%\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user`.
|
||||
|
||||
For comparison, my file is reproduced below:
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets">
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<LibraryPath>$(CRYPTOPP)\$(Platform)\Output\$(Configuration);$(BOOST)\lib\$(Platform);$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>$(CRYPTOPP);$(BOOST)\include\boost-$(BOOSTVER);$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup />
|
||||
<ItemGroup />
|
||||
</Project>
|
||||
|
||||
|
||||
If you want to build x64 binaries as well, you'll want to edit or create the
|
||||
file `%localappdata%\Microsoft\MSBuild\v4.0\Microsoft.Cpp.x64.user`. If you
|
||||
followed the steps outlined earlier you can copy (or link) the win32 file to
|
||||
the x64 one.
|
||||
|
||||
## Anti-Climatic End ##
|
||||
|
||||
After following the above instructions, you'll be able to build Debug Win32,
|
||||
Debug x64, Release Win32, and Release x64 i2pd binaries.
|
||||
BIN
Win32/Resource.rc
Normal file
BIN
Win32/Resource.rc
Normal file
Binary file not shown.
@@ -1,27 +1,30 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.30501.0
|
||||
VisualStudioVersion = 12.0.30723.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "i2pd", "i2pd.vcxproj", "{930568EC-31C9-406A-AD1C-9636DF5D8FAA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.Deploy.0 = Debug|Win32
|
||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|x64.Build.0 = Debug|x64
|
||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.Build.0 = Release|Win32
|
||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.Deploy.0 = Release|Win32
|
||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|x64.ActiveCfg = Release|x64
|
||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(Performance) = preSolution
|
||||
HasPerformanceSessions = true
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -5,10 +5,18 @@
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\AddressBook.cpp" />
|
||||
@@ -34,8 +42,10 @@
|
||||
<ClCompile Include="..\SAM.cpp" />
|
||||
<ClCompile Include="..\SSU.cpp" />
|
||||
<ClCompile Include="..\SSUData.cpp" />
|
||||
<ClCompile Include="..\SSUSession.cpp" />
|
||||
<ClCompile Include="..\Streaming.cpp" />
|
||||
<ClCompile Include="..\Destination.cpp" />
|
||||
<ClCompile Include="..\Datagram.cpp" />
|
||||
<ClCompile Include="..\Destination.cpp" />
|
||||
<ClCompile Include="..\TransitTunnel.cpp" />
|
||||
<ClCompile Include="..\Transports.cpp" />
|
||||
<ClCompile Include="..\Tunnel.cpp" />
|
||||
@@ -46,8 +56,7 @@
|
||||
<ClCompile Include="..\util.cpp" />
|
||||
<ClCompile Include="..\SOCKS.cpp" />
|
||||
<ClCompile Include="..\I2PTunnel.cpp" />
|
||||
<ClCompile Include="..\ClientContext.cpp" />
|
||||
<ClCompile Include="..\Datagram.cpp" />
|
||||
<ClCompile Include="..\ClientContext.cpp" />
|
||||
<ClCompile Include="Win32Service.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -74,8 +83,10 @@
|
||||
<ClInclude Include="..\SAM.h" />
|
||||
<ClInclude Include="..\SSU.h" />
|
||||
<ClInclude Include="..\SSUData.h" />
|
||||
<ClInclude Include="..\SSUSession.h" />
|
||||
<ClInclude Include="..\Streaming.h" />
|
||||
<ClInclude Include="..\Destination.h" />
|
||||
<ClInclude Include="..\Datagram.h" />
|
||||
<ClInclude Include="..\Destination.h" />
|
||||
<ClInclude Include="..\Timestamp.h" />
|
||||
<ClInclude Include="..\TransitTunnel.h" />
|
||||
<ClInclude Include="..\Transports.h" />
|
||||
@@ -92,10 +103,13 @@
|
||||
<ClInclude Include="..\version.h" />
|
||||
<ClInclude Include="..\Signature.h" />
|
||||
<ClInclude Include="..\ClientContext.h" />
|
||||
<ClCompile Include="..\TransportSession.h" />
|
||||
<ClCompile Include="..\Datagram.h" />
|
||||
<ClInclude Include="..\TransportSession.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="Win32Service.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Resource.rc" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{930568EC-31C9-406A-AD1C-9636DF5D8FAA}</ProjectGuid>
|
||||
<RootNamespace>i2pd</RootNamespace>
|
||||
@@ -104,15 +118,28 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -120,19 +147,36 @@
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>E:\build\cryptopp562;E:\build\boost_1_56_0;./..;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>E:\build\cryptopp562\Win32\Output\Debug;E:\build\boost_1_56_0\stage\lib;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>./..;$(IncludePath);$(BOOST);$(CRYPTOPP);C:\build-lib\cryptopp;C:\build-lib\boost_1_57_0\</IncludePath>
|
||||
<LibraryPath>$(BOOST)\stage\lib;C:\build-lib\cryptopp;C:\build-lib\boost_1_57_0\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
|
||||
<TargetName>$(ProjectName)_d</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>./..;$(IncludePath);$(BOOST);$(CRYPTOPP)</IncludePath>
|
||||
<LibraryPath>$(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
|
||||
<TargetName>$(ProjectName)_d</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IncludePath>E:\build\cryptopp562;E:\build\boost_1_56_0;./..;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>E:\build\cryptopp562\Win32\Output\Release;E:\build\cryptopp562\Win32\cryptopp\Release;E:\build\boost_1_56_0\stage\lib;E:\build\cryptopp562\Win32\cryptlib\DLL-Import Release;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>./..;$(IncludePath);$(BOOST);C:\build-lib\boost_1_57_0\;C:\build-lib</IncludePath>
|
||||
<LibraryPath>C:\build-lib\boost_1_57_0\stage\lib;C:\build-lib\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>./..;$(IncludePath);$(BOOST);$(CRYPTOPP)</IncludePath>
|
||||
<LibraryPath>$(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
@@ -147,26 +191,82 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
<Version>0.2</Version>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_MBCS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
<Version>0.2</Version>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level2</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>false</OptimizeReferences>
|
||||
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
<Version>
|
||||
</Version>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AssemblyIdentity>
|
||||
</AssemblyIdentity>
|
||||
<ComponentFileName>
|
||||
</ComponentFileName>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>false</OptimizeReferences>
|
||||
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
<Version>
|
||||
</Version>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
||||
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AssemblyIdentity>
|
||||
@@ -178,4 +278,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -123,6 +123,18 @@
|
||||
<ClCompile Include="..\SAM.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SSUSession.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Datagram.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Destination.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ClientContext.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\Identity.h">
|
||||
@@ -245,5 +257,28 @@
|
||||
<ClInclude Include="..\SAM.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\SSUSession.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Datagram.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Destination.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ClientContext.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\TransportSession.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Resource.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
BIN
Win32/ictoopie.ico
Normal file
BIN
Win32/ictoopie.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
@@ -1,10 +1,10 @@
|
||||
|
||||
#define I2Pd_AppName "i2pd"
|
||||
#define I2Pd_ver "0.1"
|
||||
#define I2Pd_AppName "i2pd"
|
||||
#define I2Pd_ver "0.2"
|
||||
|
||||
[Setup]
|
||||
AppName={#I2Pd_AppName}
|
||||
AppVersion={#I2Pd_ver}
|
||||
AppName={#I2Pd_AppName}
|
||||
AppVersion={#I2Pd_ver}
|
||||
DefaultDirName={pf}\I2Pd
|
||||
DefaultGroupName=I2Pd
|
||||
UninstallDisplayIcon={app}\I2Pd.exe
|
||||
@@ -13,27 +13,50 @@ SolidCompression=yes
|
||||
OutputDir=.
|
||||
LicenseFile=.\..\LICENSE
|
||||
OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver}
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
|
||||
|
||||
[Files]
|
||||
Source: "i2pd.exe"; DestDir: "{app}"
|
||||
Source: "x64\Release\i2pd.exe"; DestDir: "{app}"; DestName: "i2pd.exe"; Check: Is64BitInstallMode
|
||||
Source: "Release\i2pd.exe"; DestDir: "{app}"; Check: not Is64BitInstallMode
|
||||
Source: "..\README.md"; DestDir: "{app}"; DestName: "Readme.txt"; AfterInstall: ConvertLineEndings
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\I2Pd"; Filename: "{app}\i2pd.exe"
|
||||
Name: "{group}\Readme"; Filename: "{app}\Readme.txt"
|
||||
|
||||
|
||||
[Registry]
|
||||
Root: HKCU; Subkey: "Environment"; ValueName: "Path"; ValueType: "string"; ValueData: "{app};{olddata}"; Check: NotOnPathAlready(); Flags: preservestringtype;
|
||||
|
||||
[Code]
|
||||
|
||||
var
|
||||
DefaultTop,
|
||||
DefaultLeft,
|
||||
DefaultTop,
|
||||
DefaultLeft,
|
||||
DefaultHeight,
|
||||
DefaultBackTop,
|
||||
DefaultNextTop,
|
||||
DefaultBackTop,
|
||||
DefaultNextTop,
|
||||
DefaultCancelTop,
|
||||
DefaultBevelTop,
|
||||
DefaultBevelTop,
|
||||
DefaultOuterHeight: Integer;
|
||||
|
||||
const
|
||||
const
|
||||
LicenseHeight = 400;
|
||||
LF = #10;
|
||||
CR = #13;
|
||||
CRLF = CR + LF;
|
||||
|
||||
procedure ConvertLineEndings();
|
||||
var
|
||||
FilePath : String;
|
||||
FileContents : String;
|
||||
begin
|
||||
FilePath := ExpandConstant(CurrentFileName)
|
||||
LoadStringFromFile(FilePath, FileContents);
|
||||
StringChangeEx(FileContents, LF, CRLF, False);
|
||||
SaveStringToFile(FilePath, FileContents, False);
|
||||
end;
|
||||
|
||||
procedure InitializeWizard();
|
||||
begin
|
||||
@@ -67,7 +90,7 @@ begin
|
||||
WizardForm.BackButton.Top := DefaultBackTop + (LicenseHeight - DefaultHeight);
|
||||
WizardForm.Bevel.Top := DefaultBevelTop + (LicenseHeight - DefaultHeight);
|
||||
end
|
||||
else
|
||||
else
|
||||
begin
|
||||
WizardForm.Top := DefaultTop;
|
||||
WizardForm.Left := DefaultLeft;
|
||||
@@ -78,4 +101,49 @@ begin
|
||||
WizardForm.BackButton.Top := DefaultBackTop;
|
||||
WizardForm.Bevel.Top := DefaultBevelTop;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function NotOnPathAlready(): Boolean;
|
||||
var
|
||||
BinDir, Path: String;
|
||||
begin
|
||||
Log('Checking if i2pd dir is already in the %PATH%');
|
||||
if RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', Path) then
|
||||
begin // Successfully read the value
|
||||
Log('HKCUEnvironmentPATH = ' + Path);
|
||||
BinDir := ExpandConstant('{app}');
|
||||
Log('Looking for i2pd dir in %PATH%: ' + BinDir + ' in ' + Path);
|
||||
if Pos(LowerCase(BinDir), Lowercase(Path)) = 0 then
|
||||
begin
|
||||
Log('Did not find i2pd dir in %PATH% so I will add it');
|
||||
Result := True;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Log('Found i2pd dir in %PATH% so will not add it again');
|
||||
Result := False;
|
||||
end
|
||||
end
|
||||
else // The key probably doesn't exist
|
||||
begin
|
||||
Log('Could not access HKCUEnvironmentPATH so I assume that it is OK to add it');
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
||||
var
|
||||
BinDir, Path: String;
|
||||
begin
|
||||
if (CurUninstallStep = usPostUninstall)
|
||||
and (RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'PATH', Path)) then
|
||||
begin
|
||||
BinDir := ExpandConstant('{app}');
|
||||
if Pos(LowerCase(BinDir) + ';', Lowercase(Path)) <> 0 then
|
||||
begin
|
||||
StringChange(Path, BinDir + ';', '');
|
||||
RegWriteStringValue(HKEY_CURRENT_USER, 'Environment', 'PATH', Path);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
57
Win32/nsi/helper_readme.nsh
Normal file
57
Win32/nsi/helper_readme.nsh
Normal file
@@ -0,0 +1,57 @@
|
||||
!verbose push
|
||||
!verbose 3
|
||||
|
||||
!ifndef _MUI_EXTRAPAGES_NSH
|
||||
!define _MUI_EXTRAPAGES_NSH
|
||||
|
||||
!ifmacrondef MUI_EXTRAPAGE_README & MUI_PAGE_README & MUI_UNPAGE_README & ReadmeLangStrings
|
||||
|
||||
!macro MUI_EXTRAPAGE_README UN ReadmeFile
|
||||
!verbose push
|
||||
!verbose 3
|
||||
!define MUI_PAGE_HEADER_TEXT "$(${UN}ReadmeHeader)"
|
||||
!define MUI_PAGE_HEADER_SUBTEXT "$(${UN}ReadmeSubHeader)"
|
||||
!define MUI_LICENSEPAGE_TEXT_TOP "$(${UN}ReadmeTextTop)"
|
||||
!define MUI_LICENSEPAGE_TEXT_BOTTOM "$(${UN}ReadmeTextBottom)"
|
||||
!define MUI_LICENSEPAGE_BUTTON "$(^NextBtn)"
|
||||
!insertmacro MUI_${UN}PAGE_LICENSE "${ReadmeFile}"
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
!define ReadmeRun "!insertmacro MUI_EXTRAPAGE_README"
|
||||
|
||||
|
||||
!macro MUI_PAGE_README ReadmeFile
|
||||
!verbose push
|
||||
!verbose 3
|
||||
${ReadmeRun} "" "${ReadmeFile}"
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
|
||||
!macro MUI_UNPAGE_README ReadmeFile
|
||||
!verbose push
|
||||
!verbose 3
|
||||
${ReadmeRun} "UN" "${ReadmeFile}"
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
|
||||
!macro ReadmeLangStrings UN MUI_LANG ReadmeHeader ReadmeSubHeader ReadmeTextTop ReadmeTextBottom
|
||||
!verbose push
|
||||
!verbose 3
|
||||
LangString ${UN}ReadmeHeader ${MUI_LANG} "${ReadmeHeader}"
|
||||
LangString ${UN}ReadmeSubHeader ${MUI_LANG} "${ReadmeSubHeader}"
|
||||
LangString ${UN}ReadmeTextTop ${MUI_LANG} "${ReadmeTextTop}"
|
||||
LangString ${UN}ReadmeTextBottom ${MUI_LANG} "${ReadmeTextBottom}"
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
!define ReadmeLanguage `!insertmacro ReadmeLangStrings ""`
|
||||
|
||||
!define Un.ReadmeLanguage `!insertmacro ReadmeLangStrings "UN"`
|
||||
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!verbose pop
|
||||
419
Win32/nsi/servicelib.nsh
Normal file
419
Win32/nsi/servicelib.nsh
Normal file
@@ -0,0 +1,419 @@
|
||||
; NSIS SERVICE LIBRARY - servicelib.nsh
|
||||
; Version 1.8.1 - Jun 21th, 2013
|
||||
; Questions/Comments - dselkirk@hotmail.com
|
||||
;
|
||||
; Description:
|
||||
; Provides an interface to window services
|
||||
;
|
||||
; Inputs:
|
||||
; action - systemlib action ie. create, delete, start, stop, pause,
|
||||
; continue, installed, running, status
|
||||
; name - name of service to manipulate
|
||||
; param - action parameters; usage: var1=value1;var2=value2;...etc.
|
||||
; (don't forget to add a ';' after the last value!)
|
||||
;
|
||||
; Actions:
|
||||
; create - creates a new windows service
|
||||
; Parameters:
|
||||
; path - path to service executable
|
||||
; autostart - automatically start with system ie. 1|0
|
||||
; interact - interact with the desktop ie. 1|0
|
||||
; depend - service dependencies
|
||||
; user - user that runs the service
|
||||
; password - password of the above user
|
||||
; display - display name in service's console
|
||||
; description - Description of service
|
||||
; starttype - start type (supersedes autostart)
|
||||
; servicetype - service type (supersedes interact)
|
||||
;
|
||||
; delete - deletes a windows service
|
||||
; start - start a stopped windows service
|
||||
; stop - stops a running windows service
|
||||
; pause - pauses a running windows service
|
||||
; continue - continues a paused windows service
|
||||
; installed - is the provided service installed
|
||||
; Parameters:
|
||||
; action - if true then invokes the specified action
|
||||
; running - is the provided service running
|
||||
; Parameters:
|
||||
; action - if true then invokes the specified action
|
||||
; status - check the status of the provided service
|
||||
;
|
||||
; Usage:
|
||||
; Method 1:
|
||||
; Push "action"
|
||||
; Push "name"
|
||||
; Push "param"
|
||||
; Call Service
|
||||
; Pop $0 ;response
|
||||
;
|
||||
; Method 2:
|
||||
; !insertmacro SERVICE "action" "name" "param"
|
||||
;
|
||||
; History:
|
||||
; 1.0 - 09/15/2003 - Initial release
|
||||
; 1.1 - 09/16/2003 - Changed &l to i, thx brainsucker
|
||||
; 1.2 - 02/29/2004 - Fixed documentation.
|
||||
; 1.3 - 01/05/2006 - Fixed interactive flag and pop order (Kichik)
|
||||
; 1.4 - 12/07/2006 - Added display and depend, fixed datatypes (Vitoco)
|
||||
; 1.5 - 06/25/2008 - Added description of service.(DeSafe.com/liuqixing#gmail.com)
|
||||
; 1.5.1 - 06/12/2009 - Added use of __UNINSTALL__
|
||||
; 1.6 - 08/02/2010 - Fixed description implementation (Anders)
|
||||
; 1.7 - 04/11/2010 - Added get running service process id (Nico)
|
||||
; 1.8 - 24/03/2011 - Added starttype and servicetype (Sergius)
|
||||
; 1.8.1 - 21/06/2013 - Added dynamic ASCII & Unicode support (Zinthose)
|
||||
|
||||
!ifndef SERVICELIB
|
||||
!define SERVICELIB
|
||||
|
||||
!define SC_MANAGER_ALL_ACCESS 0x3F
|
||||
!define SC_STATUS_PROCESS_INFO 0x0
|
||||
!define SERVICE_ALL_ACCESS 0xF01FF
|
||||
|
||||
!define SERVICE_CONTROL_STOP 1
|
||||
!define SERVICE_CONTROL_PAUSE 2
|
||||
!define SERVICE_CONTROL_CONTINUE 3
|
||||
|
||||
!define SERVICE_STOPPED 0x1
|
||||
!define SERVICE_START_PENDING 0x2
|
||||
!define SERVICE_STOP_PENDING 0x3
|
||||
!define SERVICE_RUNNING 0x4
|
||||
!define SERVICE_CONTINUE_PENDING 0x5
|
||||
!define SERVICE_PAUSE_PENDING 0x6
|
||||
!define SERVICE_PAUSED 0x7
|
||||
|
||||
!define SERVICE_KERNEL_DRIVER 0x00000001
|
||||
!define SERVICE_FILE_SYSTEM_DRIVER 0x00000002
|
||||
!define SERVICE_WIN32_OWN_PROCESS 0x00000010
|
||||
!define SERVICE_WIN32_SHARE_PROCESS 0x00000020
|
||||
!define SERVICE_INTERACTIVE_PROCESS 0x00000100
|
||||
|
||||
|
||||
!define SERVICE_BOOT_START 0x00000000
|
||||
!define SERVICE_SYSTEM_START 0x00000001
|
||||
!define SERVICE_AUTO_START 0x00000002
|
||||
!define SERVICE_DEMAND_START 0x00000003
|
||||
!define SERVICE_DISABLED 0x00000004
|
||||
|
||||
## Added by Zinthose for Native Unicode Support
|
||||
!ifdef NSIS_UNICODE
|
||||
!define APITAG "W"
|
||||
!else
|
||||
!define APITAG "A"
|
||||
!endif
|
||||
|
||||
!macro SERVICE ACTION NAME PARAM
|
||||
Push '${ACTION}'
|
||||
Push '${NAME}'
|
||||
Push '${PARAM}'
|
||||
!ifdef __UNINSTALL__
|
||||
Call un.Service
|
||||
!else
|
||||
Call Service
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
!macro FUNC_GETPARAM
|
||||
Push $0
|
||||
Push $1
|
||||
Push $2
|
||||
Push $3
|
||||
Push $4
|
||||
Push $5
|
||||
Push $6
|
||||
Push $7
|
||||
Exch 8
|
||||
Pop $1 ;name
|
||||
Exch 8
|
||||
Pop $2 ;source
|
||||
StrCpy $0 ""
|
||||
StrLen $7 $2
|
||||
StrCpy $3 0
|
||||
lbl_loop:
|
||||
IntCmp $3 $7 0 0 lbl_done
|
||||
StrLen $4 "$1="
|
||||
StrCpy $5 $2 $4 $3
|
||||
StrCmp $5 "$1=" 0 lbl_next
|
||||
IntOp $5 $3 + $4
|
||||
StrCpy $3 $5
|
||||
lbl_loop2:
|
||||
IntCmp $3 $7 0 0 lbl_done
|
||||
StrCpy $6 $2 1 $3
|
||||
StrCmp $6 ";" 0 lbl_next2
|
||||
IntOp $6 $3 - $5
|
||||
StrCpy $0 $2 $6 $5
|
||||
Goto lbl_done
|
||||
lbl_next2:
|
||||
IntOp $3 $3 + 1
|
||||
Goto lbl_loop2
|
||||
lbl_next:
|
||||
IntOp $3 $3 + 1
|
||||
Goto lbl_loop
|
||||
lbl_done:
|
||||
Pop $5
|
||||
Pop $4
|
||||
Pop $3
|
||||
Pop $2
|
||||
Pop $1
|
||||
Exch 2
|
||||
Pop $6
|
||||
Pop $7
|
||||
Exch $0
|
||||
!macroend
|
||||
|
||||
!macro CALL_GETPARAM VAR NAME DEFAULT LABEL
|
||||
Push $1
|
||||
Push ${NAME}
|
||||
Call ${UN}GETPARAM
|
||||
Pop $6
|
||||
StrCpy ${VAR} "${DEFAULT}"
|
||||
StrCmp $6 "" "${LABEL}" 0
|
||||
StrCpy ${VAR} $6
|
||||
!macroend
|
||||
|
||||
!macro FUNC_SERVICE UN
|
||||
Push $0
|
||||
Push $1
|
||||
Push $2
|
||||
Push $3
|
||||
Push $4
|
||||
Push $5
|
||||
Push $6
|
||||
Push $7
|
||||
Exch 8
|
||||
Pop $1 ;param
|
||||
Exch 8
|
||||
Pop $2 ;name
|
||||
Exch 8
|
||||
Pop $3 ;action
|
||||
;$0 return
|
||||
;$4 OpenSCManager
|
||||
;$5 OpenService
|
||||
|
||||
StrCpy $0 "false"
|
||||
System::Call 'advapi32::OpenSCManager${APITAG}(n, n, i ${SC_MANAGER_ALL_ACCESS}) i.r4'
|
||||
IntCmp $4 0 lbl_done
|
||||
StrCmp $3 "create" lbl_create
|
||||
System::Call 'advapi32::OpenService${APITAG}(i r4, t r2, i ${SERVICE_ALL_ACCESS}) i.r5'
|
||||
IntCmp $5 0 lbl_done
|
||||
|
||||
lbl_select:
|
||||
StrCmp $3 "delete" lbl_delete
|
||||
StrCmp $3 "start" lbl_start
|
||||
StrCmp $3 "stop" lbl_stop
|
||||
StrCmp $3 "pause" lbl_pause
|
||||
StrCmp $3 "continue" lbl_continue
|
||||
StrCmp $3 "installed" lbl_installed
|
||||
StrCmp $3 "running" lbl_running
|
||||
StrCmp $3 "status" lbl_status
|
||||
StrCmp $3 "processid" lbl_processid
|
||||
Goto lbl_done
|
||||
|
||||
; create service
|
||||
lbl_create:
|
||||
Push $R1 ;depend
|
||||
Push $R2 ;user
|
||||
Push $R3 ;password
|
||||
Push $R4 ;servicetype/interact
|
||||
Push $R5 ;starttype/autostart
|
||||
Push $R6 ;path
|
||||
Push $R7 ;display
|
||||
Push $R8 ;description
|
||||
|
||||
!insertmacro CALL_GETPARAM $R1 "depend" "n" "lbl_depend"
|
||||
StrCpy $R1 't "$R1"'
|
||||
lbl_depend:
|
||||
StrCmp $R1 "n" 0 lbl_machine ;old name of depend param
|
||||
!insertmacro CALL_GETPARAM $R1 "machine" "n" "lbl_machine"
|
||||
StrCpy $R1 't "$R1"'
|
||||
lbl_machine:
|
||||
|
||||
!insertmacro CALL_GETPARAM $R2 "user" "n" "lbl_user"
|
||||
StrCpy $R2 't "$R2"'
|
||||
lbl_user:
|
||||
|
||||
!insertmacro CALL_GETPARAM $R3 "password" "n" "lbl_password"
|
||||
StrCpy $R3 't "$R3"'
|
||||
lbl_password:
|
||||
|
||||
!insertmacro CALL_GETPARAM $R4 "interact" "${SERVICE_WIN32_OWN_PROCESS}" "lbl_interact"
|
||||
StrCpy $6 ${SERVICE_WIN32_OWN_PROCESS}
|
||||
IntCmp $R4 0 +2
|
||||
IntOp $6 $6 | ${SERVICE_INTERACTIVE_PROCESS}
|
||||
StrCpy $R4 $6
|
||||
lbl_interact:
|
||||
|
||||
!insertmacro CALL_GETPARAM $R4 "servicetype" "$R4" "lbl_servicetype"
|
||||
lbl_servicetype:
|
||||
|
||||
!insertmacro CALL_GETPARAM $R5 "autostart" "${SERVICE_DEMAND_START}" "lbl_autostart"
|
||||
StrCpy $6 ${SERVICE_DEMAND_START}
|
||||
IntCmp $R5 0 +2
|
||||
StrCpy $6 ${SERVICE_AUTO_START}
|
||||
StrCpy $R5 $6
|
||||
lbl_autostart:
|
||||
|
||||
!insertmacro CALL_GETPARAM $R5 "starttype" "$R5" "lbl_starttype"
|
||||
lbl_starttype:
|
||||
|
||||
!insertmacro CALL_GETPARAM $R6 "path" "n" "lbl_path"
|
||||
lbl_path:
|
||||
|
||||
!insertmacro CALL_GETPARAM $R7 "display" "$2" "lbl_display"
|
||||
lbl_display:
|
||||
|
||||
!insertmacro CALL_GETPARAM $R8 "description" "$2" "lbl_description"
|
||||
lbl_description:
|
||||
|
||||
System::Call 'advapi32::CreateService${APITAG}(i r4, t r2, t R7, i ${SERVICE_ALL_ACCESS}, \
|
||||
i R4, i R5, i 0, t R6, n, n, $R1, $R2, $R3) i.r6'
|
||||
|
||||
; write description of service (SERVICE_CONFIG_DESCRIPTION)
|
||||
System::Call 'advapi32::ChangeServiceConfig2${APITAG}(ir6,i1,*t "$R8")i.R7'
|
||||
strcmp $R7 "error" 0 lbl_descriptioncomplete
|
||||
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\$2" "Description" $R8
|
||||
lbl_descriptioncomplete:
|
||||
|
||||
Pop $R8
|
||||
Pop $R7
|
||||
Pop $R6
|
||||
Pop $R5
|
||||
Pop $R4
|
||||
Pop $R3
|
||||
Pop $R2
|
||||
Pop $R1
|
||||
StrCmp $6 0 lbl_done lbl_good
|
||||
|
||||
; delete service
|
||||
lbl_delete:
|
||||
System::Call 'advapi32::DeleteService(i r5) i.r6'
|
||||
StrCmp $6 0 lbl_done lbl_good
|
||||
|
||||
; start service
|
||||
lbl_start:
|
||||
System::Call 'advapi32::StartService${APITAG}(i r5, i 0, i 0) i.r6'
|
||||
StrCmp $6 0 lbl_done lbl_good
|
||||
|
||||
; stop service
|
||||
lbl_stop:
|
||||
Push $R1
|
||||
System::Call '*(i,i,i,i,i,i,i) i.R1'
|
||||
System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_STOP}, i $R1) i'
|
||||
System::Free $R1
|
||||
Pop $R1
|
||||
StrCmp $6 0 lbl_done lbl_good
|
||||
|
||||
; pause service
|
||||
lbl_pause:
|
||||
Push $R1
|
||||
System::Call '*(i,i,i,i,i,i,i) i.R1'
|
||||
System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_PAUSE}, i $R1) i'
|
||||
System::Free $R1
|
||||
Pop $R1
|
||||
StrCmp $6 0 lbl_done lbl_good
|
||||
|
||||
; continue service
|
||||
lbl_continue:
|
||||
Push $R1
|
||||
System::Call '*(i,i,i,i,i,i,i) i.R1'
|
||||
System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_CONTINUE}, i $R1) i'
|
||||
System::Free $R1
|
||||
Pop $R1
|
||||
StrCmp $6 0 lbl_done lbl_good
|
||||
|
||||
; is installed
|
||||
lbl_installed:
|
||||
!insertmacro CALL_GETPARAM $7 "action" "" "lbl_good"
|
||||
StrCpy $3 $7
|
||||
Goto lbl_select
|
||||
|
||||
; is service running
|
||||
lbl_running:
|
||||
Push $R1
|
||||
System::Call '*(i,i,i,i,i,i,i) i.R1'
|
||||
System::Call 'advapi32::QueryServiceStatus(i r5, i $R1) i'
|
||||
System::Call '*$R1(i, i.r6)'
|
||||
System::Free $R1
|
||||
Pop $R1
|
||||
IntFmt $6 "0x%X" $6
|
||||
StrCmp $6 ${SERVICE_RUNNING} 0 lbl_done
|
||||
!insertmacro CALL_GETPARAM $7 "action" "" "lbl_good"
|
||||
StrCpy $3 $7
|
||||
Goto lbl_select
|
||||
|
||||
lbl_status:
|
||||
Push $R1
|
||||
System::Call '*(i,i,i,i,i,i,i) i.R1'
|
||||
System::Call 'advapi32::QueryServiceStatus(i r5, i $R1) i'
|
||||
System::Call '*$R1(i, i .r6)'
|
||||
System::Free $R1
|
||||
Pop $R1
|
||||
IntFmt $6 "0x%X" $6
|
||||
StrCpy $0 "running"
|
||||
IntCmp $6 ${SERVICE_RUNNING} lbl_done
|
||||
StrCpy $0 "stopped"
|
||||
IntCmp $6 ${SERVICE_STOPPED} lbl_done
|
||||
StrCpy $0 "start_pending"
|
||||
IntCmp $6 ${SERVICE_START_PENDING} lbl_done
|
||||
StrCpy $0 "stop_pending"
|
||||
IntCmp $6 ${SERVICE_STOP_PENDING} lbl_done
|
||||
StrCpy $0 "running"
|
||||
IntCmp $6 ${SERVICE_RUNNING} lbl_done
|
||||
StrCpy $0 "continue_pending"
|
||||
IntCmp $6 ${SERVICE_CONTINUE_PENDING} lbl_done
|
||||
StrCpy $0 "pause_pending"
|
||||
IntCmp $6 ${SERVICE_PAUSE_PENDING} lbl_done
|
||||
StrCpy $0 "paused"
|
||||
IntCmp $6 ${SERVICE_PAUSED} lbl_done
|
||||
StrCpy $0 "unknown"
|
||||
Goto lbl_done
|
||||
|
||||
lbl_processid:
|
||||
Push $R1
|
||||
Push $R2
|
||||
System::Call '*(i,i,i,i,i,i,i,i,i) i.R1'
|
||||
System::Call '*(i 0) i.R2'
|
||||
System::Call "advapi32::QueryServiceStatusEx(i r5, i ${SC_STATUS_PROCESS_INFO}, i $R1, i 36, i $R2) i"
|
||||
System::Call "*$R1(i,i,i,i,i,i,i, i .r0)"
|
||||
System::Free $R2
|
||||
System::Free $R1
|
||||
Pop $R2
|
||||
Pop $R1
|
||||
Goto lbl_done
|
||||
|
||||
lbl_good:
|
||||
StrCpy $0 "true"
|
||||
lbl_done:
|
||||
IntCmp $5 0 +2
|
||||
System::Call 'advapi32::CloseServiceHandle(i r5) n'
|
||||
IntCmp $4 0 +2
|
||||
System::Call 'advapi32::CloseServiceHandle(i r4) n'
|
||||
Pop $4
|
||||
Pop $3
|
||||
Pop $2
|
||||
Pop $1
|
||||
Exch 3
|
||||
Pop $5
|
||||
Pop $7
|
||||
Pop $6
|
||||
Exch $0
|
||||
!macroend
|
||||
|
||||
Function Service
|
||||
!insertmacro FUNC_SERVICE ""
|
||||
FunctionEnd
|
||||
|
||||
Function un.Service
|
||||
!insertmacro FUNC_SERVICE "un."
|
||||
FunctionEnd
|
||||
|
||||
Function GetParam
|
||||
!insertmacro FUNC_GETPARAM
|
||||
FunctionEnd
|
||||
|
||||
Function un.GetParam
|
||||
!insertmacro FUNC_GETPARAM
|
||||
FunctionEnd
|
||||
|
||||
!undef APITAG
|
||||
!endif
|
||||
BIN
Win32/resource.h
Normal file
BIN
Win32/resource.h
Normal file
Binary file not shown.
20
aes.cpp
20
aes.cpp
@@ -8,14 +8,6 @@ namespace crypto
|
||||
{
|
||||
|
||||
#ifdef AESNI
|
||||
|
||||
ECBCryptoAESNI::ECBCryptoAESNI ()
|
||||
{
|
||||
m_KeySchedule = m_UnalignedBuffer;
|
||||
uint8_t rem = ((uint64_t)m_KeySchedule) & 0x0f;
|
||||
if (rem)
|
||||
m_KeySchedule += (16 - rem);
|
||||
}
|
||||
|
||||
#define KeyExpansion256(round0,round1) \
|
||||
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
|
||||
@@ -40,7 +32,7 @@ namespace crypto
|
||||
"pxor %%xmm2, %%xmm3 \n" \
|
||||
"movaps %%xmm3, "#round1"(%[sched]) \n"
|
||||
|
||||
void ECBCryptoAESNI::ExpandKey (const uint8_t * key)
|
||||
void ECBCryptoAESNI::ExpandKey (const AESKey& key)
|
||||
{
|
||||
__asm__
|
||||
(
|
||||
@@ -73,7 +65,7 @@ namespace crypto
|
||||
"pxor %%xmm2, %%xmm1 \n"
|
||||
"movups %%xmm1, 224(%[sched]) \n"
|
||||
: // output
|
||||
: [key]"r"(key), [sched]"r"(m_KeySchedule) // input
|
||||
: [key]"r"((const uint8_t *)key), [sched]"r"(GetKeySchedule ()) // input
|
||||
: "%xmm1", "%xmm2", "%xmm3", "%xmm4" // clogged
|
||||
);
|
||||
}
|
||||
@@ -102,7 +94,7 @@ namespace crypto
|
||||
"movups (%[in]), %%xmm0 \n"
|
||||
EncryptAES256(sched)
|
||||
"movups %%xmm0, (%[out]) \n"
|
||||
: : [sched]"r"(m_KeySchedule), [in]"r"(in), [out]"r"(out) : "%xmm0"
|
||||
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -130,7 +122,7 @@ namespace crypto
|
||||
"movups (%[in]), %%xmm0 \n"
|
||||
DecryptAES256(sched)
|
||||
"movups %%xmm0, (%[out]) \n"
|
||||
: : [sched]"r"(m_KeySchedule), [in]"r"(in), [out]"r"(out) : "%xmm0"
|
||||
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -139,7 +131,7 @@ namespace crypto
|
||||
"aesimc %%xmm0, %%xmm0 \n" \
|
||||
"movaps %%xmm0, "#offset"(%[shed]) \n"
|
||||
|
||||
void ECBDecryptionAESNI::SetKey (const uint8_t * key)
|
||||
void ECBDecryptionAESNI::SetKey (const AESKey& key)
|
||||
{
|
||||
ExpandKey (key); // expand encryption key first
|
||||
// then invert it using aesimc
|
||||
@@ -158,7 +150,7 @@ namespace crypto
|
||||
CallAESIMC(176)
|
||||
CallAESIMC(192)
|
||||
CallAESIMC(208)
|
||||
: : [shed]"r"(m_KeySchedule) : "%xmm0"
|
||||
: : [shed]"r"(GetKeySchedule ()) : "%xmm0"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
73
aes.h
73
aes.h
@@ -4,46 +4,83 @@
|
||||
#include <inttypes.h>
|
||||
#include <cryptopp/modes.h>
|
||||
#include <cryptopp/aes.h>
|
||||
#include "Identity.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace crypto
|
||||
{
|
||||
union ChipherBlock
|
||||
struct ChipherBlock
|
||||
{
|
||||
uint8_t buf[16];
|
||||
uint64_t ll[2];
|
||||
|
||||
void operator^=(const ChipherBlock& other) // XOR
|
||||
{
|
||||
ll[0] ^= other.ll[0];
|
||||
ll[1] ^= other.ll[1];
|
||||
#if defined(__x86_64__) // for Intel x64
|
||||
__asm__
|
||||
(
|
||||
"movups (%[buf]), %%xmm0 \n"
|
||||
"movups (%[other]), %%xmm1 \n"
|
||||
"pxor %%xmm1, %%xmm0 \n"
|
||||
"movups %%xmm0, (%[buf]) \n"
|
||||
:
|
||||
: [buf]"r"(buf), [other]"r"(other.buf)
|
||||
: "%xmm0", "%xmm1", "memory"
|
||||
);
|
||||
#else
|
||||
// TODO: implement it better
|
||||
for (int i = 0; i < 16; i++)
|
||||
buf[i] ^= other.buf[i];
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
typedef i2p::data::Tag<32> AESKey;
|
||||
|
||||
template<size_t sz>
|
||||
class AESAlignedBuffer // 16 bytes alignment
|
||||
{
|
||||
public:
|
||||
|
||||
AESAlignedBuffer ()
|
||||
{
|
||||
m_Buf = m_UnalignedBuffer;
|
||||
uint8_t rem = ((uint64_t)m_Buf) & 0x0f;
|
||||
if (rem)
|
||||
m_Buf += (16 - rem);
|
||||
}
|
||||
|
||||
operator uint8_t * () { return m_Buf; };
|
||||
operator const uint8_t * () const { return m_Buf; };
|
||||
|
||||
private:
|
||||
|
||||
uint8_t m_UnalignedBuffer[sz + 15]; // up to 15 bytes alignment
|
||||
uint8_t * m_Buf;
|
||||
};
|
||||
|
||||
|
||||
#ifdef AESNI
|
||||
class ECBCryptoAESNI
|
||||
{
|
||||
public:
|
||||
|
||||
ECBCryptoAESNI ();
|
||||
uint8_t * GetKeySchedule () { return m_KeySchedule; };
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void ExpandKey (const uint8_t * key);
|
||||
void ExpandKey (const AESKey& key);
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
uint8_t * m_KeySchedule; // start of 16 bytes boundary of m_UnalignedBuffer
|
||||
uint8_t m_UnalignedBuffer[256]; // 14 rounds for AES-256, 240 + 16 bytes
|
||||
AESAlignedBuffer<240> m_KeySchedule; // 14 rounds for AES-256, 240 bytes
|
||||
};
|
||||
|
||||
class ECBEncryptionAESNI: public ECBCryptoAESNI
|
||||
{
|
||||
public:
|
||||
|
||||
void SetKey (const uint8_t * key) { ExpandKey (key); };
|
||||
void SetKey (const AESKey& key) { ExpandKey (key); };
|
||||
void Encrypt (const ChipherBlock * in, ChipherBlock * out);
|
||||
};
|
||||
|
||||
@@ -51,7 +88,7 @@ namespace crypto
|
||||
{
|
||||
public:
|
||||
|
||||
void SetKey (const uint8_t * key);
|
||||
void SetKey (const AESKey& key);
|
||||
void Decrypt (const ChipherBlock * in, ChipherBlock * out);
|
||||
};
|
||||
|
||||
@@ -64,7 +101,7 @@ namespace crypto
|
||||
{
|
||||
public:
|
||||
|
||||
void SetKey (const uint8_t * key)
|
||||
void SetKey (const AESKey& key)
|
||||
{
|
||||
m_Encryption.SetKey (key, 32);
|
||||
}
|
||||
@@ -82,7 +119,7 @@ namespace crypto
|
||||
{
|
||||
public:
|
||||
|
||||
void SetKey (const uint8_t * key)
|
||||
void SetKey (const AESKey& key)
|
||||
{
|
||||
m_Decryption.SetKey (key, 32);
|
||||
}
|
||||
@@ -105,7 +142,7 @@ namespace crypto
|
||||
|
||||
CBCEncryption () { memset (m_LastBlock.buf, 0, 16); };
|
||||
|
||||
void SetKey (const uint8_t * key) { m_ECBEncryption.SetKey (key); }; // 32 bytes
|
||||
void SetKey (const AESKey& key) { m_ECBEncryption.SetKey (key); }; // 32 bytes
|
||||
void SetIV (const uint8_t * iv) { memcpy (m_LastBlock.buf, iv, 16); }; // 16 bytes
|
||||
|
||||
void Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out);
|
||||
@@ -125,7 +162,7 @@ namespace crypto
|
||||
|
||||
CBCDecryption () { memset (m_IV.buf, 0, 16); };
|
||||
|
||||
void SetKey (const uint8_t * key) { m_ECBDecryption.SetKey (key); }; // 32 bytes
|
||||
void SetKey (const AESKey& key) { m_ECBDecryption.SetKey (key); }; // 32 bytes
|
||||
void SetIV (const uint8_t * iv) { memcpy (m_IV.buf, iv, 16); }; // 16 bytes
|
||||
|
||||
void Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out);
|
||||
@@ -142,7 +179,7 @@ namespace crypto
|
||||
{
|
||||
public:
|
||||
|
||||
void SetKeys (const uint8_t * layerKey, const uint8_t * ivKey)
|
||||
void SetKeys (const AESKey& layerKey, const AESKey& ivKey)
|
||||
{
|
||||
m_LayerEncryption.SetKey (layerKey);
|
||||
m_IVEncryption.SetKey (ivKey);
|
||||
@@ -164,7 +201,7 @@ namespace crypto
|
||||
{
|
||||
public:
|
||||
|
||||
void SetKeys (const uint8_t * layerKey, const uint8_t * ivKey)
|
||||
void SetKeys (const AESKey& layerKey, const AESKey& ivKey)
|
||||
{
|
||||
m_LayerDecryption.SetKey (layerKey);
|
||||
m_IVDecryption.SetKey (ivKey);
|
||||
|
||||
33
api/Makefile
Normal file
33
api/Makefile
Normal file
@@ -0,0 +1,33 @@
|
||||
UNAME := $(shell uname -s)
|
||||
|
||||
ifeq ($(UNAME),Darwin)
|
||||
include ../Makefile.osx
|
||||
else ifeq ($(UNAME), FreeBSD)
|
||||
include ../Makefile.bsd
|
||||
else
|
||||
include ../Makefile.linux
|
||||
endif
|
||||
|
||||
SHARED_LIB = libi2pd.so
|
||||
all: obj $(SHARED_LIB)
|
||||
|
||||
$(SHARED_LIB): $(OBJECTS:obj/%=obj/%)
|
||||
$(CXX) -shared -o $(SHARED_LIB) $^
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .cc .C .cpp .o
|
||||
|
||||
obj/%.o : ../%.cpp
|
||||
$(CXX) -o $@ $< -c $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -I.. -fPIC $(CPU_FLAGS)
|
||||
|
||||
obj/api.o: api.cpp
|
||||
$(CXX) -o obj/api.o api.cpp -c $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -I.. -fPIC $(CPU_FLAGS)
|
||||
|
||||
obj:
|
||||
mkdir -p obj
|
||||
|
||||
clean:
|
||||
rm -fr obj $(SHARED_LIB)
|
||||
|
||||
.PHONY: all
|
||||
.PHONY: clean
|
||||
108
api/api.cpp
Normal file
108
api/api.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "Log.h"
|
||||
#include "NetDb.h"
|
||||
#include "Transports.h"
|
||||
#include "Tunnel.h"
|
||||
#include "RouterContext.h"
|
||||
#include "Identity.h"
|
||||
#include "Destination.h"
|
||||
#include "util.h"
|
||||
#include "api.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
void InitI2P (int argc, char* argv[], const char * appName)
|
||||
{
|
||||
i2p::util::filesystem::SetAppName (appName);
|
||||
i2p::util::config::OptionParser(argc, argv);
|
||||
i2p::context.Init ();
|
||||
}
|
||||
|
||||
void StartI2P ()
|
||||
{
|
||||
StartLog (i2p::util::filesystem::GetAppName () + ".log");
|
||||
i2p::data::netdb.Start();
|
||||
LogPrint("NetDB started");
|
||||
i2p::transport::transports.Start();
|
||||
LogPrint("Transports started");
|
||||
i2p::tunnel::tunnels.Start();
|
||||
LogPrint("Tunnels started");
|
||||
}
|
||||
|
||||
void StopI2P ()
|
||||
{
|
||||
LogPrint("Shutdown started.");
|
||||
i2p::tunnel::tunnels.Stop();
|
||||
LogPrint("Tunnels stoped");
|
||||
i2p::transport::transports.Stop();
|
||||
LogPrint("Transports stoped");
|
||||
i2p::data::netdb.Stop();
|
||||
LogPrint("NetDB stoped");
|
||||
StopLog ();
|
||||
}
|
||||
|
||||
i2p::client::ClientDestination * CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic)
|
||||
{
|
||||
auto localDestination = new i2p::client::ClientDestination (keys, isPublic);
|
||||
localDestination->Start ();
|
||||
return localDestination;
|
||||
}
|
||||
|
||||
i2p::client::ClientDestination * CreateLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType)
|
||||
{
|
||||
auto localDestination = new i2p::client::ClientDestination (isPublic, sigType);
|
||||
localDestination->Start ();
|
||||
return localDestination;
|
||||
}
|
||||
|
||||
void DestroyLocalDestination (i2p::client::ClientDestination * dest)
|
||||
{
|
||||
if (dest)
|
||||
{
|
||||
dest->Stop ();
|
||||
delete dest;
|
||||
}
|
||||
}
|
||||
|
||||
void RequestLeaseSet (i2p::client::ClientDestination * dest, const i2p::data::IdentHash& remote)
|
||||
{
|
||||
if (dest)
|
||||
i2p::data::netdb.RequestDestination (remote, true, dest->GetTunnelPool ());
|
||||
}
|
||||
|
||||
i2p::stream::Stream * CreateStream (i2p::client::ClientDestination * dest, const i2p::data::IdentHash& remote)
|
||||
{
|
||||
auto leaseSet = i2p::data::netdb.FindLeaseSet (remote);
|
||||
if (leaseSet)
|
||||
{
|
||||
auto stream = dest->CreateStream (*leaseSet);
|
||||
stream->Send (nullptr, 0); // connect
|
||||
return stream;
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestLeaseSet (dest, remote);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptStream (i2p::client::ClientDestination * dest, const i2p::stream::StreamingDestination::Acceptor& acceptor)
|
||||
{
|
||||
if (dest)
|
||||
dest->AcceptStreams (acceptor);
|
||||
}
|
||||
|
||||
void DestroyStream (i2p::stream::Stream * stream)
|
||||
{
|
||||
if (stream)
|
||||
{
|
||||
stream->Close ();
|
||||
i2p::stream::DeleteStream (stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
31
api/api.h
Normal file
31
api/api.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef API_H__
|
||||
#define API_H__
|
||||
|
||||
#include "Identity.h"
|
||||
#include "Destination.h"
|
||||
#include "Streaming.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
// initialization start and stop
|
||||
void InitI2P (int argc, char* argv[], const char * appName);
|
||||
void StartI2P ();
|
||||
void StopI2P ();
|
||||
|
||||
// destinations
|
||||
i2p::client::ClientDestination * CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true);
|
||||
i2p::client::ClientDestination * CreateLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1); // transient destinations usually not published
|
||||
void DestoroyLocalDestination (i2p::client::ClientDestination * dest);
|
||||
|
||||
// streams
|
||||
void RequestLeaseSet (i2p::client::ClientDestination * dest, const i2p::data::IdentHash& remote);
|
||||
i2p::stream::Stream * CreateStream (i2p::client::ClientDestination * dest, const i2p::data::IdentHash& remote);
|
||||
void AcceptStream (i2p::client::ClientDestination * dest, const i2p::stream::StreamingDestination::Acceptor& acceptor);
|
||||
void DestroyStream (i2p::stream::Stream * stream);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
19
api/filelist.mk
Normal file
19
api/filelist.mk
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
CPP_FILES := ../CryptoConst.cpp ../base64.cpp ../NTCPSession.cpp ../RouterInfo.cpp \
|
||||
../Transports.cpp ../RouterContext.cpp ../NetDb.cpp ../LeaseSet.cpp Tunnel.cpp \
|
||||
../TunnelEndpoint.cpp ../TunnelGateway.cpp ../TransitTunnel.cpp ../I2NPProtocol.cpp \
|
||||
../Log.cpp ../Garlic.cpp ../Streaming.cpp ../Destination.cpp ../Identity.cpp \
|
||||
../SSU.cpp ../SSUSession.cpp ../SSUData.cpp ../util.cpp ../Reseed.cpp ../SSUData.cpp \
|
||||
../aes.cpp ../TunnelPool.cpp ../AddressBook.cpp ../Datagram.cpp api.cpp
|
||||
|
||||
|
||||
H_FILES := ../CryptoConst.h ../base64.h ../NTCPSession.h ../RouterInfo.h ../Transports.h \
|
||||
../RouterContext.h ../NetDb.h ../LeaseSet.h ../Tunnel.h ../TunnelEndpoint.h \
|
||||
../TunnelGateway.h ../TransitTunnel.h ../I2NPProtocol.h ../Log.h ../Garlic.h \
|
||||
../Streaming.h ../Destination.h ../Identity.h ../SSU.h ../SSUSession.h ../SSUData.h \
|
||||
../util.h ../Reseed.h ../SSUData.h ../aes.h ../TunnelPool.h ../AddressBook.h ../version.h \
|
||||
../Signature.h ../TransportSession.h ../Datagram.h api.h
|
||||
|
||||
OBJECTS = $(addprefix obj/, $(notdir $(CPP_FILES:.cpp=.o)))
|
||||
|
||||
@@ -114,7 +114,8 @@ am_i2p_OBJECTS = AddressBook.$(OBJEXT) CryptoConst.$(OBJEXT) \
|
||||
Transports.$(OBJEXT) Tunnel.$(OBJEXT) TunnelEndpoint.$(OBJEXT) \
|
||||
TunnelGateway.$(OBJEXT) TunnelPool.$(OBJEXT) UPnP.$(OBJEXT) \
|
||||
aes.$(OBJEXT) base64.$(OBJEXT) i2p.$(OBJEXT) util.$(OBJEXT) \
|
||||
SAM.$(OBJEXT) Destination.$(OBJEXT)
|
||||
SAM.$(OBJEXT) Destination.$(OBJEXT) ClientContext.$(OBJEXT) \
|
||||
Datagram.$(OBJEXT) SSUSession.$(OBJEXT)
|
||||
i2p_OBJECTS = $(am_i2p_OBJECTS)
|
||||
i2p_LDADD = $(LDADD)
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
@@ -325,7 +326,7 @@ i2p_SOURCES = AddressBook.cpp CryptoConst.cpp Daemon.cpp \
|
||||
Transports.cpp Tunnel.cpp TunnelEndpoint.cpp \
|
||||
TunnelGateway.cpp TunnelPool.cpp UPnP.cpp aes.cpp \
|
||||
base64.cpp i2p.cpp util.cpp SAM.cpp Destination.cpp \
|
||||
ClientContext.cpp DataFram.cpp \
|
||||
ClientContext.cpp DataFram.cpp SSUSession.cpp \
|
||||
\
|
||||
AddressBook.h CryptoConst.h Daemon.h ElGamal.h \
|
||||
Garlic.h HTTPProxy.h HTTPServer.h I2NPProtocol.h \
|
||||
@@ -337,7 +338,7 @@ i2p_SOURCES = AddressBook.cpp CryptoConst.cpp Daemon.cpp \
|
||||
TunnelConfig.h TunnelEndpoint.h TunnelGateway.h \
|
||||
TunnelPool.h UPnP.h aes.h base64.h config.h hmac.h \
|
||||
util.h version.h Destination.h ClientContext.h \
|
||||
TransportSession.h Datagram.h
|
||||
TransportSession.h Datagram.h SSUSession.h
|
||||
|
||||
AM_LDFLAGS = @BOOST_DATE_TIME_LIB@ @BOOST_FILESYSTEM_LIB@ \
|
||||
@BOOST_PROGRAM_OPTIONS_LIB@ @BOOST_REGEX_LIB@ \
|
||||
@@ -487,6 +488,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SAM.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientContext.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Datagram.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SSUSession.Po@am__quote@
|
||||
|
||||
.cpp.o:
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
|
||||
12
filelist.mk
12
filelist.mk
@@ -3,17 +3,17 @@
|
||||
CPP_FILES := CryptoConst.cpp base64.cpp NTCPSession.cpp RouterInfo.cpp Transports.cpp \
|
||||
RouterContext.cpp NetDb.cpp LeaseSet.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelGateway.cpp \
|
||||
TransitTunnel.cpp I2NPProtocol.cpp Log.cpp Garlic.cpp HTTPServer.cpp Streaming.cpp \
|
||||
Destination.cpp Identity.cpp SSU.cpp util.cpp Reseed.cpp DaemonLinux.cpp SSUData.cpp \
|
||||
aes.cpp SOCKS.cpp UPnP.cpp TunnelPool.cpp HTTPProxy.cpp AddressBook.cpp Daemon.cpp \
|
||||
I2PTunnel.cpp SAM.cpp ClientContext.cpp Datagram.cpp i2p.cpp
|
||||
Destination.cpp Identity.cpp SSU.cpp SSUSession.cpp SSUData.cpp util.cpp Reseed.cpp \
|
||||
DaemonLinux.cpp SSUData.cpp aes.cpp SOCKS.cpp UPnP.cpp TunnelPool.cpp HTTPProxy.cpp \
|
||||
AddressBook.cpp Daemon.cpp I2PTunnel.cpp SAM.cpp ClientContext.cpp Datagram.cpp i2p.cpp
|
||||
|
||||
|
||||
H_FILES := CryptoConst.h base64.h NTCPSession.h RouterInfo.h Transports.h \
|
||||
RouterContext.h NetDb.h LeaseSet.h Tunnel.h TunnelEndpoint.h TunnelGateway.h \
|
||||
TransitTunnel.h I2NPProtocol.h Log.h Garlic.h HTTPServer.h Streaming.h Destination.h \
|
||||
Identity.h SSU.h util.h Reseed.h DaemonLinux.h SSUData.h i2p.h aes.h SOCKS.h \
|
||||
UPnP.h TunnelPool.h HTTPProxy.h AddressBook.h Daemon.h I2PTunnel.h version.h \
|
||||
Signature.h SAM.h ClientContext.h TransportSession.h Datagram.h
|
||||
Identity.h SSU.h SSUSession.h SSUData.h util.h Reseed.h DaemonLinux.h SSUData.h \
|
||||
aes.h SOCKS.h UPnP.h TunnelPool.h HTTPProxy.h AddressBook.h Daemon.h I2PTunnel.h \
|
||||
version.h Signature.h SAM.h ClientContext.h TransportSession.h Datagram.h
|
||||
|
||||
|
||||
OBJECTS = $(addprefix obj/, $(notdir $(CPP_FILES:.cpp=.o)))
|
||||
|
||||
21
hmac.h
21
hmac.h
@@ -5,6 +5,7 @@
|
||||
#include <string.h>
|
||||
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
|
||||
#include <cryptopp/md5.h>
|
||||
#include "Identity.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
@@ -13,17 +14,19 @@ namespace crypto
|
||||
const uint64_t IPAD = 0x3636363636363636;
|
||||
const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C;
|
||||
|
||||
inline void HMACMD5Digest (uint8_t * msg, size_t len, const uint8_t * key, uint8_t * digest)
|
||||
typedef i2p::data::Tag<32> MACKey;
|
||||
|
||||
inline void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest)
|
||||
// key is 32 bytes
|
||||
// digest is 16 bytes
|
||||
// block size is 64 bytes
|
||||
{
|
||||
uint64_t buf[256];
|
||||
// ikeypad
|
||||
buf[0] = ((uint64_t *)key)[0] ^ IPAD;
|
||||
buf[1] = ((uint64_t *)key)[1] ^ IPAD;
|
||||
buf[2] = ((uint64_t *)key)[2] ^ IPAD;
|
||||
buf[3] = ((uint64_t *)key)[3] ^ IPAD;
|
||||
buf[0] = key.GetLL ()[0] ^ IPAD;
|
||||
buf[1] = key.GetLL ()[1] ^ IPAD;
|
||||
buf[2] = key.GetLL ()[2] ^ IPAD;
|
||||
buf[3] = key.GetLL ()[3] ^ IPAD;
|
||||
buf[4] = IPAD;
|
||||
buf[5] = IPAD;
|
||||
buf[6] = IPAD;
|
||||
@@ -35,10 +38,10 @@ namespace crypto
|
||||
CryptoPP::Weak1::MD5().CalculateDigest (hash, (uint8_t *)buf, len + 64);
|
||||
|
||||
// okeypad
|
||||
buf[0] = ((uint64_t *)key)[0] ^ OPAD;
|
||||
buf[1] = ((uint64_t *)key)[1] ^ OPAD;
|
||||
buf[2] = ((uint64_t *)key)[2] ^ OPAD;
|
||||
buf[3] = ((uint64_t *)key)[3] ^ OPAD;
|
||||
buf[0] = key.GetLL ()[0] ^ OPAD;
|
||||
buf[1] = key.GetLL ()[1] ^ OPAD;
|
||||
buf[2] = key.GetLL ()[2] ^ OPAD;
|
||||
buf[3] = key.GetLL ()[3] ^ OPAD;
|
||||
buf[4] = OPAD;
|
||||
buf[5] = OPAD;
|
||||
buf[6] = OPAD;
|
||||
|
||||
88
util.cpp
88
util.cpp
@@ -15,6 +15,11 @@
|
||||
#include "util.h"
|
||||
#include "Log.h"
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD_kernel__)
|
||||
#include <sys/types.h>
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#include <shlobj.h>
|
||||
@@ -96,6 +101,18 @@ namespace config
|
||||
|
||||
namespace filesystem
|
||||
{
|
||||
std::string appName ("i2pd");
|
||||
|
||||
void SetAppName (const std::string& name)
|
||||
{
|
||||
appName = name;
|
||||
}
|
||||
|
||||
std::string GetAppName ()
|
||||
{
|
||||
return appName;
|
||||
}
|
||||
|
||||
const boost::filesystem::path &GetDataDir()
|
||||
{
|
||||
static boost::filesystem::path path;
|
||||
@@ -173,10 +190,10 @@ namespace filesystem
|
||||
// Windows
|
||||
char localAppData[MAX_PATH];
|
||||
SHGetFolderPath(NULL, CSIDL_APPDATA, 0, NULL, localAppData);
|
||||
return boost::filesystem::path(std::string(localAppData) + "\\i2pd");
|
||||
return boost::filesystem::path(std::string(localAppData) + "\\" + appName);
|
||||
#else
|
||||
if (i2p::util::config::GetArg("-service", 0)) // use system folder
|
||||
return boost::filesystem::path("/var/lib/i2pd");
|
||||
return boost::filesystem::path(std::string ("/var/lib/") + appName);
|
||||
boost::filesystem::path pathRet;
|
||||
char* pszHome = getenv("HOME");
|
||||
if (pszHome == NULL || strlen(pszHome) == 0)
|
||||
@@ -187,10 +204,10 @@ namespace filesystem
|
||||
// Mac
|
||||
pathRet /= "Library/Application Support";
|
||||
boost::filesystem::create_directory(pathRet);
|
||||
return pathRet / "i2pd";
|
||||
return pathRet / appName;
|
||||
#else
|
||||
// Unix
|
||||
return pathRet / ".i2pd";
|
||||
return pathRet / (std::string (".") + appName);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -389,10 +406,65 @@ namespace http
|
||||
query_.assign(query_i, url_s.end());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace net
|
||||
{
|
||||
int GetMTU (const boost::asio::ip::address& localAddress)
|
||||
{
|
||||
#if defined(__linux__) || defined(__FreeBSD_kernel__)
|
||||
ifaddrs * ifaddr, * ifa = nullptr;
|
||||
if (getifaddrs(&ifaddr) == -1)
|
||||
{
|
||||
LogPrint (eLogError, "Can't excute getifaddrs");
|
||||
return 0;
|
||||
}
|
||||
int family = 0;
|
||||
// loook for interface matching local address
|
||||
for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
|
||||
{
|
||||
if (!ifa->ifa_addr) continue;
|
||||
family = ifa->ifa_addr->sa_family;
|
||||
if (family == AF_INET && localAddress.is_v4 ())
|
||||
{
|
||||
sockaddr_in * sa = (sockaddr_in *)ifa->ifa_addr;
|
||||
if (!memcmp (&sa->sin_addr, localAddress.to_v4 ().to_bytes ().data (), 4))
|
||||
break; // address matches
|
||||
}
|
||||
else if (family == AF_INET6 && localAddress.is_v6 ())
|
||||
{
|
||||
sockaddr_in6 * sa = (sockaddr_in6 *)ifa->ifa_addr;
|
||||
if (!memcmp (&sa->sin6_addr, localAddress.to_v6 ().to_bytes ().data (), 16))
|
||||
break; // address matches
|
||||
}
|
||||
}
|
||||
int mtu = 0;
|
||||
if (ifa && family) // interface found?
|
||||
{
|
||||
int fd = socket (family, SOCK_DGRAM, 0);
|
||||
if (fd > 0)
|
||||
{
|
||||
ifreq ifr;
|
||||
strncpy (ifr.ifr_name, ifa->ifa_name, IFNAMSIZ); // set interface for query
|
||||
if (ioctl (fd, SIOCGIFMTU, &ifr) >= 0)
|
||||
mtu = ifr.ifr_mtu; // MTU
|
||||
else
|
||||
LogPrint (eLogError, "Failed to run ioctl");
|
||||
close (fd);
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Failed to create datagram socket");
|
||||
}
|
||||
else
|
||||
LogPrint (eLogWarning, "Interface for local address", localAddress.to_string (), " not found");
|
||||
|
||||
freeifaddrs (ifaddr);
|
||||
return mtu;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // Namespace end
|
||||
}
|
||||
} // util
|
||||
} // i2p
|
||||
|
||||
9
util.h
9
util.h
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
@@ -24,6 +25,9 @@ namespace util
|
||||
|
||||
namespace filesystem
|
||||
{
|
||||
void SetAppName (const std::string& name);
|
||||
std::string GetAppName ();
|
||||
|
||||
const boost::filesystem::path &GetDataDir();
|
||||
std::string GetFullPath (const std::string& filename);
|
||||
boost::filesystem::path GetDefaultDataDir();
|
||||
@@ -49,6 +53,11 @@ namespace util
|
||||
std::string pass_;
|
||||
};
|
||||
}
|
||||
|
||||
namespace net
|
||||
{
|
||||
int GetMTU (const boost::asio::ip::address& localAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user