Browse Source

Clean up secure random, add packet definitions for update distribution facility.

Adam Ierymenko 11 years ago
parent
commit
17778a36ba
2 changed files with 80 additions and 22 deletions
  1. 50 2
      node/Packet.hpp
  2. 30 20
      node/Utils.cpp

+ 50 - 2
node/Packet.hpp

@@ -566,7 +566,7 @@ public:
 		 */
 		VERB_MULTICAST_LIKE = 9,
 
-		/* Network member certificate:
+		/* Network member certificate replication/push:
 		 *   <[...] serialized certificate of membership>
 		 *   [ ... additional certificates may follow ...]
 		 *
@@ -598,6 +598,9 @@ public:
 		 *
 		 * ERROR response payload:
 		 *   <[8] 64-bit network ID>
+		 *
+		 * Support is optional. Nodes should return UNSUPPORTED_OPERATION if
+		 * not supported or enabled.
 		 */
 		VERB_NETWORK_CONFIG_REQUEST = 11,
 
@@ -612,7 +615,52 @@ public:
 		 * It does not generate an OK or ERROR message, and is treated only as
 		 * a hint to refresh now.
 		 */
-		VERB_NETWORK_CONFIG_REFRESH = 12
+		VERB_NETWORK_CONFIG_REFRESH = 12,
+
+		/* Request information about a shared file:
+		 *   <[1] flags, currently unused and must be 0>
+		 *   <[2] 16-bit length of filename>
+		 *   <[...] name of file being requested>
+		 *
+		 * OK response payload (indicates that we have and will share):
+		 *   <[1] flags, currently unused and must be 0>
+		 *   <[2] 16-bit length of filename>
+		 *   <[...] name of file being requested>
+		 *   <[64] full length SHA-512 hash of file contents>
+		 *   <[4] 32-bit length of file in bytes>
+		 *   <[5] Signing ZeroTier One identity address>
+		 *   <[2] 16-bit length of signature of SHA-512 hash>
+		 *   <[...] signature of SHA-512 hash>
+		 *
+		 * ERROR response payload:
+		 *   <[2] 16-bit length of filename>
+		 *   <[...] name of file being requested>
+		 *
+		 * Support is optional. Nodes should return UNSUPPORTED_OPERATION if
+		 * not supported or enabled.
+		 */
+		VERB_FILE_INFO_REQUEST = 13,
+
+		/* Request a piece of a shared file
+		 *   <[16] first 16 bytes of SHA-512 of file being requested>
+		 *   <[4] 32-bit index of desired chunk>
+		 *   <[2] 16-bit length of desired chunk>
+		 *
+		 * OK response payload:
+		 *   <[16] first 16 bytes of SHA-512 of file being requested>
+		 *   <[4] 32-bit index of desired chunk>
+		 *   <[2] 16-bit length of desired chunk>
+		 *   <[...] the chunk>
+		 *
+		 * ERROR response payload:
+		 *   <[16] first 16 bytes of SHA-512 of file being requested>
+		 *   <[4] 32-bit index of desired chunk>
+		 *   <[2] 16-bit length of desired chunk>
+		 *
+		 * Support is optional. Nodes should return UNSUPPORTED_OPERATION if
+		 * not supported or enabled.
+		 */
+		VERB_FILE_BLOCK_REQUEST = 14
 	};
 
 	/**

+ 30 - 20
node/Utils.cpp

@@ -186,31 +186,41 @@ unsigned int Utils::unhex(const char *hex,unsigned int hexlen,void *buf,unsigned
 void Utils::getSecureRandom(void *buf,unsigned int bytes)
 {
 	static Mutex randomLock;
-	static char randbuf[32768];
+	static char randbuf[16384];
 	static unsigned int randptr = sizeof(randbuf);
-#ifdef __WINDOWS__
 	static Salsa20 s20;
-	volatile bool s20Initialized = false;
-#endif
+	static bool randInitialized = false;
 
 	Mutex::Lock _l(randomLock);
+
+	// A Salsa20 instance is used to mangle whatever our base
+	// random source happens to be.
+	if (!randInitialized) {
+		memset(randbuf,0,sizeof(randbuf));
+		char s20key[33];
+		uint64_t s20iv = now();
+		Utils::snprintf(s20key,sizeof(s20key),"%.16llx%.16llx",(unsigned long long)now(),(unsigned long long)((void *)&s20iv));
+		s20.init(s20key,256,&s20iv,8);
+	}
+
 	for(unsigned int i=0;i<bytes;++i) {
 		if (randptr >= sizeof(randbuf)) {
 #ifdef __UNIX_LIKE__
-			int fd = ::open("/dev/urandom",O_RDONLY);
-			if (fd < 0) {
-				fprintf(stderr,"FATAL ERROR: unable to open /dev/urandom: %s"ZT_EOL_S,strerror(errno));
-				exit(-1);
-			}
-			if ((int)::read(fd,randbuf,sizeof(randbuf)) != (int)sizeof(randbuf)) {
-				fprintf(stderr,"FATAL ERROR: unable to read from /dev/urandom"ZT_EOL_S);
-				exit(-1);
+			{
+				int fd = ::open("/dev/urandom",O_RDONLY);
+				if (fd < 0) {
+					fprintf(stderr,"FATAL ERROR: unable to open /dev/urandom: %s"ZT_EOL_S,strerror(errno));
+					exit(-1);
+				}
+				if ((int)::read(fd,randbuf,sizeof(randbuf)) != (int)sizeof(randbuf)) {
+					fprintf(stderr,"FATAL ERROR: unable to read from /dev/urandom"ZT_EOL_S);
+					exit(-1);
+				}
+				::close(fd);
 			}
-			::close(fd);
 #else
 #ifdef __WINDOWS__
-			if (!s20Initialized) {
-				s20Initialized = true;
+			{
 				char ktmp[32];
 				char ivtmp[8];
 				for(int i=0;i<32;++i) ktmp[i] = (char)rand();
@@ -218,17 +228,17 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
 				double now = Utils::nowf();
 				memcpy(ktmp,&now,sizeof(now));
 				DWORD tmp = GetCurrentProcessId();
-				memcpy(ktmp + sizeof(double),&tmp,sizeof(tmp));
+				memcpy(ktmp + sizeof(now),&tmp,sizeof(tmp));
 				tmp = GetTickCount();
-				memcpy(ktmp + sizeof(double) + sizeof(DWORD),&tmp,sizeof(tmp));
-				s20.init(ktmp,256,ivtmp);
-				for(int i=0;i<sizeof(randbuf);++i) randbuf[i] = (char)rand();
+				memcpy(ktmp + sizeof(now) + sizeof(DWORD),&tmp,sizeof(tmp));
+				Salsa20 s20tmp(ktmp,256,ivtmp,8);
+				s20tmp.encrypt(randbuf,randbuf,sizeof(randbuf));
 			}
-			s20.encrypt(randbuf,randbuf,sizeof(randbuf));
 #else
 no getSecureRandom() implementation;
 #endif
 #endif
+			s20.encrypt(randbuf,randbuf,sizeof(randbuf));
 			randptr = 0;
 		}
 		((char *)buf)[i] = randbuf[randptr++];