From 9cf734b74a750b8af0c628809c16be57eef1ff21 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 25 Jul 2013 13:24:39 -0400 Subject: Sane-ify Address, get rid of goofy union thingy. --- node/Identity.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'node/Identity.hpp') diff --git a/node/Identity.hpp b/node/Identity.hpp index 5cdfe9f8..e5a11d6a 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -307,7 +307,7 @@ public: inline void serialize(Buffer &b,bool includePrivate = false) const throw(std::out_of_range) { - b.append(_address.data(),ZT_ADDRESS_LENGTH); + _address.appendTo(b); b.append((unsigned char)IDENTITY_TYPE_NIST_P_521); b.append((unsigned char)(_publicKey.size() & 0xff)); b.append(_publicKey.data(),_publicKey.size()); -- cgit v1.2.3 From 439e602d5a5712d1b33fb19d558d0e9fdf784703 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 29 Jul 2013 16:18:29 -0400 Subject: Fix a bunch of errors due to minor method signature changes, still a work in progress. --- node/Identity.hpp | 2 +- node/Network.cpp | 18 +++++++----------- node/Network.hpp | 32 +++++++++++++++++++++++++++----- node/Packet.cpp | 5 +++-- node/Packet.hpp | 22 +++++++++++----------- node/PacketDecoder.cpp | 16 ++++++++-------- node/PacketDecoder.hpp | 2 +- 7 files changed, 58 insertions(+), 39 deletions(-) (limited to 'node/Identity.hpp') diff --git a/node/Identity.hpp b/node/Identity.hpp index e5a11d6a..a9f78c8a 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -340,7 +340,7 @@ public: unsigned int p = startAt; - _address = b.field(p,ZT_ADDRESS_LENGTH); + _address.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; if (b[p++] != IDENTITY_TYPE_NIST_P_521) diff --git a/node/Network.cpp b/node/Network.cpp index 34a9a85b..696426e4 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -37,23 +37,19 @@ namespace ZeroTier { -void Network::Certificate::sign(const Identity &with) +void Network::Certificate::_shaForSignature(unsigned char *dig) const { - unsigned char dig[32]; SHA256_CTX sha; SHA256_Init(&sha); unsigned char zero = 0; for(const_iterator i(begin());i!=end();++i) { - if (i->first != "sig") { - SHA256_Update(&sha,&zero,1); - SHA256_Update(&sha,(const unsigned char *)i->first.data(),i->first.length()); - SHA256_Update(&sha,&zero,1); - SHA256_Update(&sha,(const unsigned char *)i->second.data(),i->second.length()); - SHA256_Update(&sha,&zero,1); - } + SHA256_Update(&sha,&zero,1); + SHA256_Update(&sha,(const unsigned char *)i->first.data(),i->first.length()); + SHA256_Update(&sha,&zero,1); + SHA256_Update(&sha,(const unsigned char *)i->second.data(),i->second.length()); + SHA256_Update(&sha,&zero,1); } SHA256_Final(dig,&sha); - (*this)["sig"] = with.sign(dig); } static const std::string _DELTA_PREFIX("~"); @@ -71,7 +67,7 @@ bool Network::Certificate::qualifyMembership(const Network::Certificate &mc) con const_iterator deltaField(find(_DELTA_PREFIX + myField->first)); if (deltaField == end()) { - // If there is no delta, compare for equality (e.g. node, nwid) + // If there is no delta, compare on simple equality if (myField->second != theirField->second) return false; } else { diff --git a/node/Network.hpp b/node/Network.hpp index 359e2ce5..c13f00a4 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -129,7 +129,7 @@ public: } /** - * Set the timestamp and max-delta + * Set the timestamp and timestamp max-delta * * @param ts Timestamp in ms since epoch * @param maxDelta Maximum difference between two peers on the same network @@ -144,11 +144,31 @@ public: } /** - * Set or update the sig field to contain a signature + * Sign this certificate * * @param with Signing identity -- the identity of this network's controller + * @return Signature or empty string on failure */ - void sign(const Identity &with); + inline std::string sign(const Identity &with) const + { + unsigned char dig[32]; + _shaForSignature(dig); + return with.sign(dig); + } + + /** + * Verify this certificate's signature + * + * @param with Signing identity -- the identity of this network's controller + * @param sig Signature + * @param siglen Length of signature in bytes + */ + inline bool verify(const Identity &with,const void *sig,unsigned int siglen) const + { + unsigned char dig[32]; + _shaForSignature(dig); + return with.verifySignature(dig,sig,siglen); + } /** * Check if another peer is indeed a current member of this network @@ -157,13 +177,15 @@ public: * delta in this certificate. Fields without ~fields are compared for * equality. * - * This does not verify the certificate's signature! The signature - * must be verified first. + * This does not verify the certificate's signature! * * @param mc Peer membership certificate * @return True if mc's membership in this network is current */ bool qualifyMembership(const Certificate &mc) const; + + private: + void _shaForSignature(unsigned char *dig) const; }; /** diff --git a/node/Packet.cpp b/node/Packet.cpp index d3c0a3af..0aae1e2d 100644 --- a/node/Packet.cpp +++ b/node/Packet.cpp @@ -42,7 +42,7 @@ const char *Packet::verbString(Verb v) case VERB_FRAME: return "FRAME"; case VERB_MULTICAST_FRAME: return "MULTICAST_FRAME"; case VERB_MULTICAST_LIKE: return "MULTICAST_LIKE"; - case VERB_NETWORK_PERMISSION_CERTIFICATE: return "NETWORK_PERMISSION_CERTIFICATE"; + case VERB_NETWORK_MEMBERSHIP_CERTIFICATE: return "NETWORK_MEMBERSHIP_CERTIFICATE"; case VERB_NETWORK_CONFIG_REQUEST: return "NETWORK_CONFIG_REQUEST"; case VERB_NETWORK_CONFIG_REFRESH: return "NETWORK_CONFIG_REFRESH"; } @@ -60,7 +60,8 @@ const char *Packet::errorString(ErrorCode e) case ERROR_IDENTITY_COLLISION: return "IDENTITY_COLLISION"; case ERROR_IDENTITY_INVALID: return "IDENTITY_INVALID"; case ERROR_UNSUPPORTED_OPERATION: return "UNSUPPORTED_OPERATION"; - case ERROR_NO_NETWORK_CERTIFICATE_ON_FILE: return "NO_NETWORK_CERTIFICATE_ON_FILE"; + case ERROR_NO_MEMBER_CERTIFICATE_ON_FILE: return "NO_MEMBER_CERTIFICATE_ON_FILE"; + case ERROR_MEMBER_CERTIFICATE_UNQUALIFIED: return "MEMBER_CERTIFICATE_UNQUALIFIED"; } return "(unknown)"; } diff --git a/node/Packet.hpp b/node/Packet.hpp index 2f88ac37..85ccb466 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -465,21 +465,17 @@ public: */ VERB_MULTICAST_FRAME = 9, - /* Network permission certificate: + /* Network member certificate for sending peer: * <[8] 64-bit network ID> - * <[1] flags (currently unused, must be 0)> - * <[2] 16-bit length of qualifying fields> - * <[...] string-serialized dictionary of qualifying fields> + * <[2] 16-bit length of certificate> + * <[...] string-serialized certificate dictionary> * <[2] 16-bit length of signature> - * <[...] ECDSA signature of my binary serialized identity and timestamp> - * - * This message is used to send ahead of time a certificate proving - * this node has permission to communicate on a private network. + * <[...] ECDSA signature of certificate> * * OK is generated on acceptance. ERROR is returned on failure. In both * cases the payload is the network ID. */ - VERB_NETWORK_PERMISSION_CERTIFICATE = 10, + VERB_NETWORK_MEMBERSHIP_CERTIFICATE = 10, /* Network configuration request: * <[8] 64-bit network ID> @@ -506,7 +502,8 @@ public: * <[8] 64-bit network ID> * * This message can be sent by the network configuration master node - * to request that nodes refresh their network configuration. + * to request that nodes refresh their network configuration. It can + * thus be used to "push" updates. * * It is only a hint and does not presently elicit a response. */ @@ -540,7 +537,10 @@ public: ERROR_UNSUPPORTED_OPERATION = 6, /* Message to private network rejected -- no unexpired certificate on file */ - ERROR_NO_NETWORK_CERTIFICATE_ON_FILE = 7 + ERROR_NO_MEMBER_CERTIFICATE_ON_FILE = 7, + + /* Membership certificate no longer qualified for membership in network */ + ERROR_MEMBER_CERTIFICATE_UNQUALIFIED = 8 }; /** diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp index cd9985c3..0353625c 100644 --- a/node/PacketDecoder.cpp +++ b/node/PacketDecoder.cpp @@ -102,8 +102,8 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r) return _doMULTICAST_LIKE(_r,peer); case Packet::VERB_MULTICAST_FRAME: return _doMULTICAST_FRAME(_r,peer); - case Packet::VERB_NETWORK_PERMISSION_CERTIFICATE: - return _doNETWORK_PERMISSION_CERTIFICATE(_r,peer); + case Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE: + return _doNETWORK_MEMBERSHIP_CERTIFICATE(_r,peer); case Packet::VERB_NETWORK_CONFIG_REQUEST: return _doNETWORK_CONFIG_REQUEST(_r,peer); case Packet::VERB_NETWORK_CONFIG_REFRESH: @@ -311,7 +311,7 @@ bool PacketDecoder::_doOK(const RuntimeEnvironment *_r,const SharedPtr &pe bool PacketDecoder::_doWHOIS(const RuntimeEnvironment *_r,const SharedPtr &peer) { if (payloadLength() == ZT_ADDRESS_LENGTH) { - SharedPtr p(_r->topology->getPeer(Address(payload()))); + SharedPtr p(_r->topology->getPeer(Address(payload(),ZT_ADDRESS_LENGTH))); if (p) { Packet outp(source(),_r->identity.address(),Packet::VERB_OK); outp.append((unsigned char)Packet::VERB_WHOIS); @@ -320,7 +320,7 @@ bool PacketDecoder::_doWHOIS(const RuntimeEnvironment *_r,const SharedPtr outp.encrypt(peer->cryptKey()); outp.hmacSet(peer->macKey()); _r->demarc->send(_localPort,_remoteAddress,outp.data(),outp.size(),-1); - TRACE("sent WHOIS response to %s for %s",source().toString().c_str(),Address(payload()).toString().c_str()); + TRACE("sent WHOIS response to %s for %s",source().toString().c_str(),Address(payload(),ZT_ADDRESS_LENGTH).toString().c_str()); } else { Packet outp(source(),_r->identity.address(),Packet::VERB_ERROR); outp.append((unsigned char)Packet::VERB_WHOIS); @@ -330,7 +330,7 @@ bool PacketDecoder::_doWHOIS(const RuntimeEnvironment *_r,const SharedPtr outp.encrypt(peer->cryptKey()); outp.hmacSet(peer->macKey()); _r->demarc->send(_localPort,_remoteAddress,outp.data(),outp.size(),-1); - TRACE("sent WHOIS ERROR to %s for %s (not found)",source().toString().c_str(),Address(payload()).toString().c_str()); + TRACE("sent WHOIS ERROR to %s for %s (not found)",source().toString().c_str(),Address(payload(),ZT_ADDRESS_LENGTH).toString().c_str()); } } else { TRACE("dropped WHOIS from %s(%s): missing or invalid address",source().toString().c_str(),_remoteAddress.toString().c_str()); @@ -341,7 +341,7 @@ bool PacketDecoder::_doWHOIS(const RuntimeEnvironment *_r,const SharedPtr bool PacketDecoder::_doRENDEZVOUS(const RuntimeEnvironment *_r,const SharedPtr &peer) { try { - Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH)); + Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); SharedPtr withPeer(_r->topology->getPeer(with)); if (withPeer) { unsigned int port = at(ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT); @@ -439,7 +439,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared if (network->isAllowed(source())) { if (size() > ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD) { - Address originalSubmitterAddress(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SUBMITTER_ADDRESS,ZT_ADDRESS_LENGTH)); + Address originalSubmitterAddress(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SUBMITTER_ADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); MAC fromMac(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC,6)); MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DESTINATION_MAC,6)),at(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ADI)); unsigned int hops = (*this)[ZT_PROTO_VERB_MULTICAST_FRAME_IDX_HOP_COUNT]; @@ -544,7 +544,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared return true; } -bool PacketDecoder::_doNETWORK_PERMISSION_CERTIFICATE(const RuntimeEnvironment *_r,const SharedPtr &peer) +bool PacketDecoder::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment *_r,const SharedPtr &peer) { } diff --git a/node/PacketDecoder.hpp b/node/PacketDecoder.hpp index 1cd1dca7..51408ba5 100644 --- a/node/PacketDecoder.hpp +++ b/node/PacketDecoder.hpp @@ -122,7 +122,7 @@ private: bool _doFRAME(const RuntimeEnvironment *_r,const SharedPtr &peer); bool _doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedPtr &peer); bool _doMULTICAST_FRAME(const RuntimeEnvironment *_r,const SharedPtr &peer); - bool _doNETWORK_PERMISSION_CERTIFICATE(const RuntimeEnvironment *_r,const SharedPtr &peer); + bool _doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment *_r,const SharedPtr &peer); bool _doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *_r,const SharedPtr &peer); bool _doNETWORK_CONFIG_REFRESH(const RuntimeEnvironment *_r,const SharedPtr &peer); -- cgit v1.2.3 From 2a6b74746edbfde0b0f1468cdf153263670c908a Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 2 Aug 2013 14:25:23 -0400 Subject: Netconf service itself works, time to integrate. --- netconf-service/Makefile | 5 +- netconf-service/netconf-test.cpp | 17 ++++++ netconf-service/netconf.cpp | 108 +++++++++++++++++++++++++-------------- node/Identity.hpp | 4 +- node/Service.cpp | 22 +++++--- node/Thread.cpp | 2 +- 6 files changed, 107 insertions(+), 51 deletions(-) (limited to 'node/Identity.hpp') diff --git a/netconf-service/Makefile b/netconf-service/Makefile index bd6b052c..af737a97 100644 --- a/netconf-service/Makefile +++ b/netconf-service/Makefile @@ -1,6 +1,7 @@ all: gcc -O6 -c ../ext/lz4/lz4hc.c ../ext/lz4/lz4.c - g++ -DZT_OSNAME="linux" -DZT_ARCH="x86_64" -I/usr/include/mysql -I../ext/bin/libcrypto/include -O -o netconf.service netconf.cpp ../node/Utils.cpp ../node/Identity.cpp ../node/EllipticCurveKeyPair.cpp ../node/Salsa20.cpp ../node/HMAC.cpp lz4.o lz4hc.o ../ext/bin/libcrypto/linux-x86_64/libcrypto.a -lmysqlpp + g++ -DZT_OSNAME="linux" -DZT_ARCH="x86_64" -I/usr/include/mysql -I../ext/bin/libcrypto/include -O -pthread -o netconf.service netconf.cpp ../node/Utils.cpp ../node/Identity.cpp ../node/EllipticCurveKeyPair.cpp ../node/Salsa20.cpp ../node/HMAC.cpp lz4.o lz4hc.o ../ext/bin/libcrypto/linux-x86_64/libcrypto.a -lmysqlpp + g++ -DZT_OSNAME="linux" -DZT_ARCH="x86_64" -I/usr/include/mysql -I../ext/bin/libcrypto/include -O -pthread -o netconf-test netconf-test.cpp ../node/Utils.cpp ../node/Identity.cpp ../node/EllipticCurveKeyPair.cpp ../node/Salsa20.cpp ../node/HMAC.cpp ../node/Logger.cpp ../node/Service.cpp ../node/Thread.cpp lz4.o lz4hc.o ../ext/bin/libcrypto/linux-x86_64/libcrypto.a clean: - rm -f *.o netconf.service + rm -f *.o netconf.service netconf-test diff --git a/netconf-service/netconf-test.cpp b/netconf-service/netconf-test.cpp index aadaa51d..6c7ef9f2 100644 --- a/netconf-service/netconf-test.cpp +++ b/netconf-service/netconf-test.cpp @@ -42,11 +42,13 @@ #include "../node/Identity.hpp" #include "../node/RuntimeEnvironment.hpp" #include "../node/Logger.hpp" +#include "../node/Thread.hpp" using namespace ZeroTier; static void svcHandler(void *arg,Service &svc,const Dictionary &msg) { + std::cout << msg.toString(); } int main(int argc,char **argv) @@ -59,8 +61,23 @@ int main(int argc,char **argv) std::vector population; for(;;) { + Identity id; if ((population.empty())||(rand() < (RAND_MAX / 4))) { + id.generate(); + population.push_back(id); + std::cout << "Testing with new identity: " << id.address().toString() << std::endl; } else { + id = population[rand() % population.size()]; + Thread::sleep(1000); + std::cout << "Testing with existing identity: " << id.address().toString() << std::endl; } + + Dictionary request; + request["type"] = "netconf-request"; + request["peerId"] = id.toString(false); + request["nwid"] = "6c92786fee000001"; + request["requestId"] = "12345"; + + svc.send(request); } } diff --git a/netconf-service/netconf.cpp b/netconf-service/netconf.cpp index a92ff8a0..01f33120 100644 --- a/netconf-service/netconf.cpp +++ b/netconf-service/netconf.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -71,24 +72,34 @@ #include "../node/Dictionary.hpp" #include "../node/Identity.hpp" #include "../node/Utils.hpp" +#include "../node/Mutex.hpp" using namespace ZeroTier; using namespace mysqlpp; +static Mutex stdoutWriteLock; static Connection *dbCon = (Connection *)0; static char mysqlHost[64],mysqlPort[64],mysqlDatabase[64],mysqlUser[64],mysqlPassword[64]; static void connectOrReconnect() { for(;;) { - if (dbCon) - delete dbCon; - dbCon = new Connection(mysqlDatabase,mysqlHost,mysqlUser,mysqlPassword,(unsigned int)strtol(mysqlPort,(char **)0,10)); - if (dbCon->connected()) - break; - else { - fprintf(stderr,"Unable to connect to database server.\n"); - usleep(1000); + delete dbCon; + try { + dbCon = new Connection(mysqlDatabase,mysqlHost,mysqlUser,mysqlPassword,(unsigned int)strtol(mysqlPort,(char **)0,10)); + if (dbCon->connected()) { + fprintf(stderr,"(re?)-connected to mysql server successfully\n"); + break; + } else { + fprintf(stderr,"unable to connect to database server (connection closed), trying again in 1s...\n"); + usleep(1000000); + } + } catch (std::exception &exc) { + fprintf(stderr,"unable to connect to database server (%s), trying again in 1s...\n",exc.what()); + usleep(1000000); + } catch ( ... ) { + fprintf(stderr,"unable to connect to database server (unknown exception), trying again in 1s...\n"); + usleep(1000000); } } } @@ -98,7 +109,7 @@ int main(int argc,char **argv) { char *ee = getenv("ZT_NETCONF_MYSQL_HOST"); if (!ee) { - fprintf(stderr,"Missing environment variable: ZT_NETCONF_MYSQL_HOST\n"); + fprintf(stderr,"missing environment variable: ZT_NETCONF_MYSQL_HOST\n"); return -1; } strcpy(mysqlHost,ee); @@ -108,57 +119,66 @@ int main(int argc,char **argv) else strcpy(mysqlPort,ee); ee = getenv("ZT_NETCONF_MYSQL_DATABASE"); if (!ee) { - fprintf(stderr,"Missing environment variable: ZT_NETCONF_MYSQL_DATABASE\n"); + fprintf(stderr,"missing environment variable: ZT_NETCONF_MYSQL_DATABASE\n"); return -1; } strcpy(mysqlDatabase,ee); ee = getenv("ZT_NETCONF_MYSQL_USER"); if (!ee) { - fprintf(stderr,"Missing environment variable: ZT_NETCONF_MYSQL_USER\n"); + fprintf(stderr,"missing environment variable: ZT_NETCONF_MYSQL_USER\n"); return -1; } strcpy(mysqlUser,ee); ee = getenv("ZT_NETCONF_MYSQL_PASSWORD"); if (!ee) { - fprintf(stderr,"Missing environment variable: ZT_NETCONF_MYSQL_PASSWORD\n"); + fprintf(stderr,"missing environment variable: ZT_NETCONF_MYSQL_PASSWORD\n"); return -1; } strcpy(mysqlPassword,ee); } - char buf[4096]; + char buf[131072]; std::string dictBuf; connectOrReconnect(); for(;;) { - if (read(STDIN_FILENO,buf,4) != 4) { - fprintf(stderr,"Error reading frame size from stdin\n"); - return -1; + for(int l=0;l<4;) { + int n = (int)read(STDIN_FILENO,buf + l,4 - l); + if (n < 0) { + fprintf(stderr,"error reading frame size from stdin: %s\n",strerror(errno)); + return -1; + } + l += n; } unsigned int fsize = (unsigned int)ntohl(*((const uint32_t *)buf)); + while (dictBuf.length() < fsize) { int n = (int)read(STDIN_FILENO,buf,std::min((int)sizeof(buf),(int)(fsize - dictBuf.length()))); + if (n < 0) { + fprintf(stderr,"error reading frame from stdin: %s\n",strerror(errno)); + return -1; + } for(int i=0;iconnected()) connectOrReconnect(); try { - const std::string &command = msg.get("command"); - if (command == "config") { // NETWORK_CONFIG_REQUEST packet - Identity peerIdentity(msg.get("peerIdentity")); - uint64_t nwid = strtoull(msg.get("nwid").c_str(),(char **)0,16); + const std::string &reqType = request.get("type"); + if (reqType == "netconf-request") { // NETWORK_CONFIG_REQUEST packet + Identity peerIdentity(request.get("peerId")); + uint64_t nwid = strtoull(request.get("nwid").c_str(),(char **)0,16); Dictionary meta; - if (msg.contains("meta")) - meta.fromString(msg.get("meta")); + if (request.contains("meta")) + meta.fromString(request.get("meta")); // Do quick signature check / sanity check if (!peerIdentity.locallyValidate(false)) { - fprintf(stderr,"identity failed signature check: %s",peerIdentity.toString(false).c_str()); + fprintf(stderr,"identity failed signature check: %s\n",peerIdentity.toString(false).c_str()); continue; } @@ -176,16 +196,22 @@ int main(int argc,char **argv) } } else { q = dbCon->query(); - uint64_t now = Utils::now(); - q << "INSERT INTO Node (id,creationTime,lastSeen,identity) VALUES (" << peerIdentity.address().toInt() << "," << now << "," << now << "," << peerIdentity.toString(false) << ")"; + q << "INSERT INTO Node (id,creationTime,lastSeen,identity) VALUES (" << peerIdentity.address().toInt() << "," << Utils::now() << ",0," << quote << peerIdentity.toString(false) << ")"; if (!q.exec()) { - fprintf(stderr,"Error inserting Node row for peer %s, aborting netconf request",peerIdentity.address().toString().c_str()); + fprintf(stderr,"error inserting Node row for peer %s, aborting netconf request\n",peerIdentity.address().toString().c_str()); continue; } // TODO: launch background validation } } + // Update lastSeen + { + Query q = dbCon->query(); + q << "UPDATE Node SET lastSeen = " << Utils::now() << " WHERE id = " << peerIdentity.address().toInt(); + q.exec(); + } + bool isOpen = false; { Query q = dbCon->query(); @@ -278,20 +304,26 @@ int main(int argc,char **argv) if (ipv6Static.length()) netconf["ipv6Static"] = ipv6Static; - Dictionary resp; - resp["peer"] = peerIdentity.address().toString(); - resp["nwid"] = msg.get("nwid"); - resp["requestId"] = msg.get("requestId"); - resp["netconf"] = netconf.toString(); - std::string respm = resp.toString(); - uint32_t respml = (uint32_t)htonl((uint32_t)respm.length()); - write(STDOUT_FILENO,&respml,4); - write(STDOUT_FILENO,respm.data(),respm.length()); + { + Dictionary response; + response["peer"] = peerIdentity.address().toString(); + response["nwid"] = request.get("nwid"); + response["type"] = "netconf-response"; + response["requestId"] = request.get("requestId"); + response["netconf"] = netconf.toString(); + std::string respm = response.toString(); + uint32_t respml = (uint32_t)htonl((uint32_t)respm.length()); + + stdoutWriteLock.lock(); + write(STDOUT_FILENO,&respml,4); + write(STDOUT_FILENO,respm.data(),respm.length()); + stdoutWriteLock.unlock(); + } } } catch (std::exception &exc) { - fprintf(stderr,"unexpected exception handling message: %s",exc.what()); + fprintf(stderr,"unexpected exception handling message: %s\n",exc.what()); } catch ( ... ) { - fprintf(stderr,"unexpected exception handling message: unknown exception"); + fprintf(stderr,"unexpected exception handling message: unknown exception\n"); } } } diff --git a/node/Identity.hpp b/node/Identity.hpp index a9f78c8a..1cce4fb0 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -104,7 +104,7 @@ public: _keyPair((EllipticCurveKeyPair *)0) { if (!fromString(str)) - throw std::invalid_argument("invalid string-serialized identity"); + throw std::invalid_argument(std::string("invalid string-serialized identity: ") + str); } Identity(const std::string &str) @@ -112,7 +112,7 @@ public: _keyPair((EllipticCurveKeyPair *)0) { if (!fromString(str)) - throw std::invalid_argument("invalid string-serialized identity"); + throw std::invalid_argument(std::string("invalid string-serialized identity: ") + str); } template diff --git a/node/Service.cpp b/node/Service.cpp index 88a6d15c..c614e4e4 100644 --- a/node/Service.cpp +++ b/node/Service.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -109,7 +110,7 @@ bool Service::send(const Dictionary &msg) void Service::main() throw() { - char buf[4096]; + char buf[131072]; fd_set readfds,writefds,exceptfds; struct timeval tv; @@ -126,27 +127,30 @@ void Service::main() pipe(out); pipe(err); - long pid = fork(); + long pid = vfork(); if (pid < 0) { LOG("service %s terminating: could not fork!",_name.c_str()); return; } else if (pid) { - close(in[1]); - close(out[0]); - close(err[0]); + // Parent + close(in[0]); + close(out[1]); + close(err[1]); Thread::sleep(500); // give child time to start _childStdin = in[1]; _childStdout = out[0]; _childStderr = err[0]; fcntl(_childStdout,F_SETFL,O_NONBLOCK); fcntl(_childStderr,F_SETFL,O_NONBLOCK); + _pid = pid; } else { - dup2(in[0],STDIN_FILENO); - dup2(out[1],STDOUT_FILENO); - dup2(err[1],STDERR_FILENO); + // Child close(in[1]); close(out[0]); close(err[0]); + dup2(in[0],STDIN_FILENO); + dup2(out[1],STDOUT_FILENO); + dup2(err[1],STDERR_FILENO); execl(_path.c_str(),_path.c_str(),_r->homePath.c_str(),(const char *)0); exit(-1); } @@ -169,6 +173,8 @@ void Service::main() } } + // If we've made it here, _pid is running last we checked. + FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); diff --git a/node/Thread.cpp b/node/Thread.cpp index 71cfcaea..f650f6fc 100644 --- a/node/Thread.cpp +++ b/node/Thread.cpp @@ -75,7 +75,7 @@ void Thread::join() void Thread::sleep(unsigned long ms) { - usleep(ms); + usleep(ms * 1000); } void Thread::__intl_run() -- cgit v1.2.3