diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-08-02 14:25:23 -0400 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-08-02 14:25:23 -0400 |
commit | 2a6b74746edbfde0b0f1468cdf153263670c908a (patch) | |
tree | 3e09ca56f65ea69e2d41df0a9d25ffb880270820 /netconf-service/netconf.cpp | |
parent | 741642ba531e487c18c8139c4a2e9510eed0466d (diff) | |
download | infinitytier-2a6b74746edbfde0b0f1468cdf153263670c908a.tar.gz infinitytier-2a6b74746edbfde0b0f1468cdf153263670c908a.zip |
Netconf service itself works, time to integrate.
Diffstat (limited to 'netconf-service/netconf.cpp')
-rw-r--r-- | netconf-service/netconf.cpp | 108 |
1 files changed, 70 insertions, 38 deletions
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 <string.h> #include <stdint.h> #include <unistd.h> +#include <errno.h> #include <sys/stat.h> #include <sys/types.h> #include <arpa/inet.h> @@ -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;i<n;++i) dictBuf.push_back(buf[i]); } - Dictionary msg(dictBuf); + Dictionary request(dictBuf); dictBuf = ""; if (!dbCon->connected()) 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"); } } } |