- Result of svn merge -x --ignore-eol-style -r 424:458 https://ttuki.vtt.fi/svn/p2p...
authorarno <arno@e16421f0-f15b-0410-abcd-98678b794739>
Tue, 20 Oct 2009 12:16:52 +0000 (12:16 +0000)
committerarno <arno@e16421f0-f15b-0410-abcd-98678b794739>
Tue, 20 Oct 2009 12:16:52 +0000 (12:16 +0000)
  i.e. merge of Win32 port onto trunk.

  TODO: test on Linux.

git-svn-id: https://ttuki.vtt.fi/svn/p2p-next/TUD/p2tp/trunk@459 e16421f0-f15b-0410-abcd-98678b794739

45 files changed:
SConstruct
bin.cpp
bin.h
bin64.cpp
bin64.h
bins.cpp
bins.h
compat/hirestimeofday.cpp [new file with mode: 0644]
compat/hirestimeofday.h [new file with mode: 0644]
compat/stdint.h [new file with mode: 0644]
compat/unixio.cpp [new file with mode: 0644]
compat/unixio.h [new file with mode: 0644]
compat/util.cpp [new file with mode: 0644]
compat/util.h [new file with mode: 0644]
datagram.cpp
datagram.h
ext/ledbat_controller.cpp
ext/mmap_storer.cpp
ext/seq_picker.cpp
ext/simple_selector.cpp
hashtree.cpp
hashtree.h
p2tp.cpp
p2tp.h
rarest1st.cpp
sbit.cpp
sbit.h
sendrecv.cpp
tests/SConscript
tests/bin64test.cpp
tests/binstest.cpp
tests/binstest2.cpp
tests/bintest.cpp
tests/congctrltest.cpp
tests/connecttest.cpp
tests/dgramtest.cpp
tests/freemap.cpp
tests/hashtest.cpp
tests/ledbattest.cpp
tests/ledbattest2.cpp
tests/rwtest.cpp
tests/sbit2test.cpp
tests/sbittest.cpp
tests/transfertest.cpp
transfer.cpp

index cc59e73..33970ee 100644 (file)
+# Written by Victor Grishchenko, Arno Bakker 
+# see LICENSE.txt for license information
+#
+# Requirements:
+#  - scons: Cross-platform build system    http://www.scons.org/
+#  - googletest: Google C++ Test Framework http://code.google.com/p/googletest/
+#       * Install in ..\gtest-1.4.0
+#  - google-glog: Google Logging Library for C++  http://code.google.com/p/google-glog/
+#       * Install in ..\glog-0.3.0 
+#       * I get ..\glog-0.3.0\src\windows\glog/log_severity.h(51) : error C2059: syntax error :
+#         'constant' while running scons. Apparently the ERROR constant is already defined somewhere.
+#         #undef ERROR before the def allows include.
+#
+#  - OpenSSL: http://www.slproweb.com/products/Win32OpenSSL.html
+#       * Install non-light Win32 binary in \openssl
+#       * Using a openssl-0.9.8k tar-ball doesn't work as the includes there
+#         are symbolic links which get turned into 0 length files by 7Zip. 
+#
+
 import os
 import re
+import sys
+
+DEBUG = True
 
 TestDir='tests'
 
-env = Environment(CPPPATH = ['.'])
+target = 'p2tp'
+source = [ 'bin64.cpp','hashtree.cpp','datagram.cpp','bins.cpp', 'transfer.cpp', 'compat/hirestimeofday.cpp', 'compat/util.cpp']
+
+env = Environment()
+if sys.platform == "win32":
+       # "MSVC works out of the box". Sure.
+       # Make sure scons finds cl.exe, etc.
+       env.Append ( ENV = { 'PATH' : os.environ['PATH'] } )
+
+       # Make sure scons finds std MSVC include files
+       if not 'INCLUDE' in os.environ:
+               print "p2tp: Please run scons in a Visual Studio Command Prompt"
+               sys.exit(-1)
+               
+       include = os.environ['INCLUDE']
+       include += '..\\gtest-1.4.0\\include;'
+       include += '..\\glog-0.3.0\\src\\windows;' # Funky
+       include += '\\openssl\\include;' 
+       
+       env.Append ( ENV = { 'INCLUDE' : include } )
+       
+       # Other compiler flags
+       env.Append(CPPPATH=".")
+       if DEBUG:
+               env.Append(CXXFLAGS="/Zi /Yd /MTd")
+               env.Append(LINKFLAGS="/DEBUG")
+
+       # Add simulated pread/write
+       source += ['compat/unixio.cpp']
+       # Set libs to link to
+       libs = ['libglog','ws2_32']
+       if DEBUG:
+               libs += ['gtestd','libeay32MTd']
+       else:
+               libs += ['gtest','libeay32']
+               
+       # Update lib search path
+       libpath = os.environ['LIBPATH']
+       if DEBUG:
+               libpath += '\\build\\gtest-1.4.0\\msvc\\gtest\\Debug;'
+               libpath += '\\build\\glog-0.3.0\\vsprojects\\libglog\\Debug;'
+               libpath += '\\openssl\\lib\\VC\\static;'
+       else:
+               libpath += '\\build\\gtest-1.4.0\\msvc\\gtest\\Release;'
+               libpath += '\\build\\glog-0.3.0\\vsprojects\\libglog\\Release;'
+               libpath += '\\openssl\\lib;'
+       # Somehow linker can't find uuid.lib
+       libpath += 'C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0A\\Lib;'
+       
+else:
+       # Enable the user defining external includes
+        if 'CPPPATH' in os.environ:
+           cpppath = os.environ['CPPPATH']
+       else:
+           cpppath = ""
+           print "To use external libs, set CPPPATH environment variable to list of colon-separated include dirs"
+       env.Append(CPPPATH=".:"+cpppath)
+        env.Append(LINKFLAGS="--static")
+
+       #if DEBUG:
+       #       env.Append(CXXFLAGS="-g")
+
+       # Set libs to link to
+       libs = ['stdc++','gtest','glog','pthread','crypto']
+       if 'LIBPATH' in os.environ:
+           libpath = os.environ['LIBPATH']
+       else:
+           libpath = ""
+           print "To use external libs, set LIBPATH environment variable to list of colon-separated lib dirs"
 
-env.SharedLibrary (
-    target='p2tp',
-    source = [ 'bin64.cpp','hashtree.cpp','datagram.cpp',
-               'bins.cpp', 'transfer.cpp' ],
-    LIBS=['stdc++','gtest','glog','crypto'] )
+env.StaticLibrary (
+    target= target,
+    source = source,
+    LIBS=libs,
+    LIBPATH=libpath )
 
+Export("env")
+Export("libs")
+Export("libpath")
+Export("DEBUG")
 SConscript('tests/SConscript')
diff --git a/bin.cpp b/bin.cpp
index 187dde4..0fa7996 100644 (file)
--- a/bin.cpp
+++ b/bin.cpp
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 
diff --git a/bin.h b/bin.h
index 3742b88..ed02494 100644 (file)
--- a/bin.h
+++ b/bin.h
@@ -3,34 +3,41 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #ifndef BIN_H
 #define BIN_H
 #include <assert.h>
-#include <stdint.h>
+#ifdef _MSC_VER
+    // To avoid complaints about std::max. Appears to work in VS2008
+    #undef min
+    #undef max
+    #include "compat/stdint.h"
+#else
+    #include <stdint.h>
+#endif
 #include <deque>
 
 struct bin {
        uint32_t        b;
-       
+
        static bin      NONE;
        static bin      ALL;
        static uint8_t BC[256];
        static uint8_t T0[256];
-       
+
        bin() : b(0) {}
        bin(const bin& b_) : b(b_.b) {}
        bin(uint32_t b_) : b(b_) {}
-       
+
        bin(uint8_t layer_, uint32_t offset) {
                b = lenpeak((offset+1)<<layer_);
                b -= layer() - layer_;
        }
-       
+
        static void     init ();
-       
+
        static uint8_t tailzeros (uint32_t i) {
                uint8_t ret = 0;
                if ( (i&0xffff)==0 )
@@ -39,7 +46,7 @@ struct bin {
                        ret +=8, i>>=8;
                return ret+T0[i&0xff];
        }
-       
+
        static uint8_t bitcount (uint32_t i) {
                //uint8_t* p = (uint8_t*) &i;
                //return BC[p[0]] + BC[p[1]] + BC[p[2]] + BC[p[3]];
@@ -48,67 +55,67 @@ struct bin {
                                BC[(i>>16)&0xff] +
                                BC[i>>24];
        }
-       
+
        static uint32_t blackout (uint32_t i) {
                return i|=(i|=(i|=(i|=(i|=i>>1)>>2)>>4)>>8)>>16;
        }
-       
+
        static uint32_t highbit (uint32_t i) {
                return (blackout(i)+1)>>1;
        }
-       
+
        static bool all1 (uint32_t a) {
                return !(a&(a+1));
        }
-       
+
        static bin  lenpeak (uint32_t length) {
                return (length<<1) - bitcount(length);
        }
-       
+
        static uint8_t lenlayer (uint32_t len) {
                return tailzeros(len);
        }
-       
+
        static bin  layermass (uint8_t layer) {
                return (2<<layer)-1;
        }
-       
+
        static uint32_t lastbiton (uint32_t i) {
                return (~i+1)&i;
        }
-       
+
        typedef std::deque<bin> vec;
        static vec peaks (uint32_t len);
-       
+
        static void order (vec* v);
-       
+
        operator uint32_t() const {     return b;  }
-       
+
        bin                     operator ++ () { return b++; }
        bin                     operator -- () { return b--; }
        bin                     operator ++ (int) { return ++b; }
        bin                     operator -- (int) { return --b; }
-       
+
        uint32_t        mlat() const {
                return 0;
        }
-       
+
        bin                     left() const {
                return bin(b-(mass()>>1)-1);
        }
-       
+
        bin                     right() const {
                return bin(b-1);
        }
-       
+
        bin                     right_foot() const {
                return bin(b-layer());
        }
-       
+
        bin                     left_foot() const {
                return bin(b-mass()+1);
        }
-       
+
        uint32_t        length() const {
                //assert(*this<=ALL);
                uint32_t apx = (b>>1) + 16; //if (b<=ALL-32) apx = ALL>>1;
@@ -122,50 +129,50 @@ struct bin {
                next = apx = lenpeak(next)>=b ? next : apx;
                return apx;
        }
-       
+
        uint32_t        mass() const {
                return layermass(layer());
        }
-       
+
        uint8_t         layer() const {
                uint32_t len = length();
                uint8_t topeak = lenpeak(len) - b;
                return lenlayer(len) - topeak;
        }
-       
+
        uint32_t        width () const {
                return 1<<layer();
        }
-       
+
        bin                     peak() const {
                return lenpeak(length());
        }
-       
+
        bin                     divide (uint8_t ls) const {
                uint32_t newlen = ((length()-1)>>ls) +1;
                uint8_t newlr = std::max(0,layer()-ls);
                return lenpeak(newlen) - lenlayer(newlen) + newlr;
        }
-       
+
        uint32_t        offset () const {
                return length() - width();
        }
-       
+
        bin                     modulo (uint8_t ls) const {
                if (layer()>=ls)
                        return layermass(ls);
                bin blockleft = lenpeak(((length()-1) & ~((1<<ls)-1)) + 1);
                return b - blockleft + 1;
        }
-       
+
        bin                     multiply (uint8_t ls) const {
                return b + length()*(layermass(ls)-1);
        }
-       
+
        bool            contains (bin c) const {
                return c.b<=b && c.b>b-mass();
        }
-       
+
        bin                     commonParent (bin other) const {
                uint8_t maxlayer = std::max(layer(),other.layer());
                uint32_t myoff = offset()>>maxlayer, othoff = other.offset()>>maxlayer;
@@ -173,11 +180,11 @@ struct bin {
                uint8_t toshift = bitcount(diff);
                return bin(maxlayer+toshift,myoff>>toshift);
        }
-       
+
        bin                     child (bin dir) const {
                return left().contains(dir) ? left() : right();
        }
-       
+
        bin                     parent (uint8_t g=1) const {
                uint32_t l = length();
                uint8_t h2b = layer()+g;
@@ -188,15 +195,15 @@ struct bin {
                return lenpeak(l2b) - lenlayer(l2b) + h2b;
                //length()==bin(b+1).length() ? b+1 : b+mass()+1;
        }
-       
+
        bool            is_right () const {
                return this->parent()==b+1;
        }
-       
+
        bool            is_left () const {
                return !is_right();
        }
-       
+
        bin                     sibling () const {
                return is_left() ? bin(b+mass()) : bin(b-mass());
        }
@@ -205,21 +212,21 @@ struct bin {
                assert(layer()<=top.layer());   // TERRIBLE
                assert(top.layer()>=height);
                uint8_t rel_layer;
-               if (layer()+height>=top.layer()) 
+               if (layer()+height>=top.layer())
                        rel_layer = layer()+height-top.layer();
                else
                        rel_layer = 0;//top.layer() - height;
                uint32_t rel_offset = (offset()-top.offset()) >> (top.layer()-height+rel_layer);
                return bin(rel_layer,rel_offset);
        }
-       
+
        bin                     unscoped (bin top, uint8_t height) const {
                uint32_t undermass = layermass(top.layer()-height);
                uint32_t pad = (1<<height) - length();
                uint32_t peak = (1<<(height+1))-1;
                return top - (peak-this->b) + pad - undermass*pad;
        }
-                       
+
 } ;
 
 
index 599c4df..10c4859 100644 (file)
--- a/bin64.cpp
+++ b/bin64.cpp
@@ -3,7 +3,7 @@
  *  p2tp
  *
  *  Created by Victor Grishchenko on 10/10/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include "bin64.h"
diff --git a/bin64.h b/bin64.h
index f6b2bf3..16279a9 100644 (file)
--- a/bin64.h
+++ b/bin64.h
@@ -1,8 +1,11 @@
 #ifndef BIN64_H
 #define BIN64_H
 #include <assert.h>
-#include <stdint.h>
-
+#ifdef _MSC_VER
+    #include "compat/stdint.h"
+#else
+    #include <stdint.h>
+#endif
 
 
 /** Numbering for (aligned) logarithmical bins.
@@ -23,7 +26,7 @@ struct bin64_t {
     bin64_t() : v(NONE) {}
     bin64_t(const bin64_t&b) : v(b.v) {}
     bin64_t(const uint64_t val) : v(val) {}
-    bin64_t(uint8_t layer, uint64_t offset) : 
+    bin64_t(uint8_t layer, uint64_t offset) :
         v( (offset<<(layer+1)) | ((1ULL<<layer)-1) ) {}
     operator uint64_t () const { return v; }
     uint32_t to32() const ;
@@ -41,7 +44,7 @@ struct bin64_t {
     }
 
     bin64_t sibling () const {
-        // if (v==ALL) return NONE; 
+        // if (v==ALL) return NONE;
         return bin64_t(v^(tail_bit()<<1));
     }
 
@@ -55,7 +58,7 @@ struct bin64_t {
         // courtesy of Sean Eron Anderson
         // http://graphics.stanford.edu/~seander/bithacks.html
         static const int DeBRUIJN[32] = {
-          0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 
+          0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
           31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
         };
         r += DeBRUIJN[((uint32_t)(tail*0x077CB531U))>>27];
@@ -118,24 +121,24 @@ struct bin64_t {
     bin64_t left_foot () const {
         return bin64_t(0,base_offset());
     }
-    
+
     /** Whether layer is 0. */
     bool    is_base () const {
         return !(v & 1);
     }
-    
+
     /** Depth-first in-order binary tree traversal. */
     bin64_t next_dfsio (uint8_t floor);
-    
+
     bin64_t width () const {
         return (tail_bits()+1)>>1;
     }
-    
+
     /** The array must have 64 cells, as it is the max
      number of peaks possible +1 (and there are no reason
      to assume there will be less in any given case. */
     static int peaks (uint64_t length, bin64_t* peaks) ;
-    
+
 };
 
 
index c1c7436..f546982 100644 (file)
--- a/bins.cpp
+++ b/bins.cpp
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 4/1/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include "bins.h"
diff --git a/bins.h b/bins.h
index a2540a5..e1d9130 100644 (file)
--- a/bins.h
+++ b/bins.h
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/28/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #ifndef BINS_H
diff --git a/compat/hirestimeofday.cpp b/compat/hirestimeofday.cpp
new file mode 100644 (file)
index 0000000..d98380f
--- /dev/null
@@ -0,0 +1,157 @@
+/*\r
+ * Inspired by\r
+ * - http://msdn.microsoft.com/en-us/library/ms644904%28VS.85%29.aspx\r
+ * - Python-2.6.3/Modules/timemodule.c\r
+ */\r
+\r
+#include <iostream>\r
+#include "compat/hirestimeofday.h"\r
+\r
+#ifndef _MSC_VER\r
+#include <sys/time.h>\r
+#endif\r
+\r
+namespace p2tp {\r
+\r
+HiResTimeOfDay* HiResTimeOfDay::_instance = 0;\r
+\r
+HiResTimeOfDay* HiResTimeOfDay::Instance()\r
+{\r
+       if (_instance == 0)\r
+               _instance = new HiResTimeOfDay();\r
+       return _instance;\r
+}\r
+\r
+\r
+#ifdef _MSC_VER\r
+#include <windows.h>\r
+#include <sys/timeb.h>\r
+\r
+\r
+HiResTimeOfDay::HiResTimeOfDay(void)\r
+{\r
+       frequency = getFrequency();\r
+       epochstart = getFTime();\r
+       epochcounter = getCounter();\r
+}\r
+\r
+\r
+tint HiResTimeOfDay::getTimeUSec(void)\r
+{\r
+       LARGE_INTEGER currentcounter;\r
+       tint      currentstart;\r
+\r
+       currentstart = getFTime();\r
+    currentcounter = getCounter();\r
+\r
+    if (currentcounter.QuadPart < epochcounter.QuadPart)\r
+    {\r
+\r
+       // Wrap around detected, reestablish baseline\r
+       epochstart = currentstart;\r
+       epochcounter = currentcounter;\r
+    }\r
+    return epochstart + (1000000*(currentcounter.QuadPart-epochcounter.QuadPart))/frequency.QuadPart;\r
+}\r
+\r
+\r
+// Private\r
+tint HiResTimeOfDay::getFTime()\r
+{\r
+       struct timeb t;\r
+       ftime(&t);\r
+       tint usec;\r
+       usec =  t.time * 1000000;\r
+       usec += t.millitm * 1000;\r
+       return usec;\r
+}\r
+\r
+\r
+\r
+LARGE_INTEGER HiResTimeOfDay::getFrequency(void)\r
+{\r
+    LARGE_INTEGER proc_freq;\r
+\r
+    if (!::QueryPerformanceFrequency(&proc_freq))\r
+       std::cerr << "HiResTimeOfDay: QueryPerformanceFrequency() failed";\r
+\r
+    return proc_freq;\r
+}\r
+\r
+LARGE_INTEGER HiResTimeOfDay::getCounter()\r
+{\r
+    LARGE_INTEGER counter;\r
+\r
+    DWORD_PTR oldmask = ::SetThreadAffinityMask(::GetCurrentThread(), 0);\r
+    if (!::QueryPerformanceCounter(&counter))\r
+       std::cerr << "HiResTimeOfDay: QueryPerformanceCounter() failed";\r
+    ::SetThreadAffinityMask(::GetCurrentThread(), oldmask);\r
+\r
+    return counter;\r
+}\r
+\r
+#else\r
+\r
+HiResTimeOfDay::HiResTimeOfDay(void)\r
+{\r
+}\r
+\r
+\r
+tint HiResTimeOfDay::getTimeUSec(void)\r
+{\r
+       struct timeval t;\r
+       gettimeofday(&t,NULL);\r
+       tint ret;\r
+       ret = t.tv_sec;\r
+       ret *= 1000000;\r
+       ret += t.tv_usec;\r
+       return ret;\r
+}\r
+#endif\r
+\r
+  \r
+  \r
+  \r
+// ARNOTODO: move to p2tp.cpp\r
+\r
+#ifdef _MSC_VER\r
+static WSADATA _WSAData;\r
+#endif\r
+  \r
+void LibraryInit(void)\r
+{\r
+#ifdef _MSC_VER\r
+       // win32 requires you to initialize the Winsock DLL with the desired\r
+       // specification version\r
+       WORD wVersionRequested;\r
+    wVersionRequested = MAKEWORD(2, 2);\r
+       WSAStartup(wVersionRequested, &_WSAData);\r
+#endif\r
+}\r
+  \r
+  \r
+} // end of namespace\r
+\r
+\r
+\r
+\r
+#ifdef TEST\r
+#include <iostream>\r
+\r
+using namespace p2tp;\r
+\r
+int main()\r
+{\r
+       HiResTimeOfDay *t = HiResTimeOfDay::Instance();\r
+       for (int i=0; i<100; i++)\r
+       {\r
+               tint st = t->getTimeUSec();\r
+               Sleep(1000);\r
+               tint et = t->getTimeUSec();\r
+               tint diff = et - st;\r
+               std::cout << "diffxTime is " << diff << "\n";\r
+       }\r
+       return 0;\r
+}\r
+#endif\r
+\r
diff --git a/compat/hirestimeofday.h b/compat/hirestimeofday.h
new file mode 100644 (file)
index 0000000..623a9f3
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+ * Written by Arno Bakker\r
+ * see LICENSE.txt for license information\r
+ *\r
+ * Singleton class to retrieve a time-of-day in UTC in usec in a platform-\r
+ * independent manner.\r
+ */\r
+#ifndef HIRESTIMEOFDAY_H\r
+#define HIRESTIMEOFDAY_H\r
+\r
+#ifdef _MSC_VER\r
+#include "compat/stdint.h"\r
+#include <windows.h>\r
+#else\r
+#include <stdint.h>\r
+#endif\r
+\r
+\r
+namespace p2tp {\r
+\r
+typedef int64_t tint;\r
+#define TINT_SEC ((tint)1000000)\r
+#define TINT_MSEC ((tint)1000)\r
+#define TINT_uSEC ((tint)1)\r
+#define TINT_NEVER ((tint)0x7fffffffffffffffLL)\r
+\r
+\r
+class HiResTimeOfDay\r
+{\r
+public:\r
+    HiResTimeOfDay(void);\r
+    tint getTimeUSec(void);\r
+    static HiResTimeOfDay* Instance();\r
+\r
+private:\r
+#ifdef _MSC_VER\r
+       tint     epochstart; // in usec\r
+       LARGE_INTEGER epochcounter;\r
+    LARGE_INTEGER last;\r
+    LARGE_INTEGER frequency;\r
+\r
+    tint HiResTimeOfDay::getFTime();\r
+    LARGE_INTEGER getFrequency(void);\r
+    LARGE_INTEGER getCounter(void);\r
+#endif\r
+\r
+    static HiResTimeOfDay* _instance;\r
+};\r
+\r
+};\r
+#endif\r
diff --git a/compat/stdint.h b/compat/stdint.h
new file mode 100644 (file)
index 0000000..4586324
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ * Written by Arno Bakker\r
+ * see LICENSE.txt for license information\r
+ */\r
+\r
+#ifndef STDINT_H_\r
+#define STDINT_H_\r
+\r
+typedef unsigned char uint8_t;\r
+typedef signed char int8_t;\r
+typedef unsigned short uint16_t;\r
+typedef short int16_t;\r
+typedef unsigned int uint32_t;\r
+typedef int int32_t;\r
+typedef __int64 int64_t;\r
+typedef unsigned __int64 uint64_t;\r
+\r
+#endif /* STDINT_H_ */\r
diff --git a/compat/unixio.cpp b/compat/unixio.cpp
new file mode 100644 (file)
index 0000000..1c369a6
--- /dev/null
@@ -0,0 +1,28 @@
+/*\r
+ * Written by Arno Bakker\r
+ * see LICENSE.txt for license information\r
+ */\r
+\r
+#include "compat/unixio.h"\r
+#include <io.h>\r
+#include <stdio.h>\r
+#include <winsock2.h>\r
+\r
+size_t pread(int fildes, void *buf, size_t nbyte, long offset)\r
+{\r
+       _lseek(fildes,offset,SEEK_SET);\r
+    return read(fildes,buf,nbyte);\r
+}\r
+\r
+size_t pwrite(int fildes, const void *buf, size_t nbyte, long offset)\r
+{\r
+    _lseek(fildes,offset,SEEK_SET);\r
+    return write(fildes,buf,nbyte);\r
+}\r
+\r
+\r
+int inet_aton(const char *cp, struct in_addr *inp)\r
+{\r
+       inp->S_un.S_addr = inet_addr(cp);\r
+       return 1;\r
+}\r
diff --git a/compat/unixio.h b/compat/unixio.h
new file mode 100644 (file)
index 0000000..e36a1f1
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+ * Written by Arno Bakker\r
+ * see LICENSE.txt for license information\r
+ *\r
+ * Defines UNIX like I/O calls and parameters for Win32\r
+ */\r
+\r
+#ifndef UNIXIO_H_\r
+#define UNIXIO_H_\r
+\r
+#define open(a,b,c)    _open(a,b,c)\r
+#define S_IRUSR _S_IREAD\r
+#define S_IWUSR        _S_IWRITE\r
+#define S_IRGRP _S_IREAD\r
+#define S_IROTH _S_IREAD\r
+#define ftruncate(a, b) _chsize(a,b)\r
+\r
+size_t pread(int fildes, void *buf, size_t nbyte, long offset);\r
+/** UNIX pread approximation. Does change file pointer. Is not thread-safe */\r
+size_t pwrite(int fildes, const void *buf, size_t nbyte, long offset);\r
+/** UNIX pwrite approximation. Does change file pointer. Is not thread-safe */\r
+\r
+int inet_aton(const char *cp, struct in_addr *inp);\r
+\r
+#endif /* UNIXIO_H_ */\r
diff --git a/compat/util.cpp b/compat/util.cpp
new file mode 100644 (file)
index 0000000..c352c5c
--- /dev/null
@@ -0,0 +1,37 @@
+/*\r
+ * Written by Arno Bakker\r
+ * see LICENSE.txt for license information\r
+ */\r
+\r
+#include "util.h"\r
+#include <vector>\r
+\r
+#ifdef _MSC_VER\r
+#include <windows.h>\r
+#include <Tchar.h>\r
+#endif\r
+\r
+namespace p2tp\r
+{\r
+\r
+std::string gettmpdir(void)\r
+{\r
+#ifdef _MSC_VER\r
+  DWORD result = ::GetTempPath(0, _T(""));\r
+  if (result == 0)\r
+       throw std::runtime_error("Could not get system temp path");\r
+\r
+  std::vector<TCHAR> tempPath(result + 1);\r
+  result = ::GetTempPath(static_cast<DWORD>(tempPath.size()), &tempPath[0]);\r
+  if((result == 0) || (result >= tempPath.size()))\r
+       throw std::runtime_error("Could not get system temp path");\r
+\r
+  return std::string(tempPath.begin(), tempPath.begin() + static_cast<std::size_t>(result));\r
+#else\r
+         return std::string("/tmp/");\r
+#endif\r
+}\r
+\r
+\r
+}; // namespace\r
+\r
diff --git a/compat/util.h b/compat/util.h
new file mode 100644 (file)
index 0000000..b4e542f
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+ * util.h\r
+ *\r
+ *  Created on: 20-Oct-2009\r
+ *      Author: arno\r
+ */\r
+\r
+#ifndef UTIL_H_\r
+#define UTIL_H_\r
+\r
+#include <string>\r
+\r
+namespace p2tp\r
+{\r
+       std::string gettmpdir(void);\r
+       /**\r
+        * Return path of temporary directory.\r
+        *\r
+        * From http://msdn.microsoft.com/en-us/library/aa364992%28VS.85%29.aspx\r
+        *\r
+        * TODO: Unicode... (gets hairy with open() call on Linux. Win32 has _wopen)\r
+        */\r
+\r
+\r
+};\r
+\r
+#endif /* UTIL_H_ */\r
index daccd9a..c218e66 100644 (file)
@@ -3,10 +3,17 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/9/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
-#include <arpa/inet.h>
+#include <iostream>
+
+#ifdef _MSC_VER
+    #include <winsock2.h>
+    typedef int socklen_t;
+#else
+    #include <arpa/inet.h>
+#endif
 #include <glog/logging.h>
 #include "datagram.h"
 
@@ -16,7 +23,7 @@ tint Datagram::now = Datagram::Time();
 uint32_t Datagram::Address::LOCALHOST = INADDR_LOOPBACK;
 
 int Datagram::Send () {
-       int r = sendto(sock,buf+offset,length-offset,0,
+       int r = sendto(sock,(const char *)buf+offset,length-offset,0,
                                   (struct sockaddr*)&(addr.addr),sizeof(struct sockaddr_in));
        offset=0;
        length=0;
@@ -27,17 +34,24 @@ int Datagram::Send () {
 int Datagram::Recv () {
        socklen_t addrlen = sizeof(struct sockaddr_in);
        offset = 0;
-       length = recvfrom (sock, buf, MAXDGRAMSZ, 0, 
+       length = recvfrom (sock, (char *)buf, MAXDGRAMSZ, 0,
                                           (struct sockaddr*)&(addr), &addrlen);
        if (length<0)
+#ifdef _MSC_VER
+               PLOG(ERROR)<<"on recv" << WSAGetLastError() << "\n";
+#else
                PLOG(ERROR)<<"on recv";
+#endif
        now = Time();
        return length;
 }
 
 
-int Datagram::Wait (int sockcnt, int* sockets, tint usec) {
-       LOG(INFO)<<"waiting for "<<sockcnt;
+SOCKET Datagram::Wait (int sockcnt, SOCKET* sockets, tint usec) {
+       // ARNOTODO: LOG commented out, it causes a crash on win32 (in a strlen()
+       // done as part of a std::local::name() ??
+       //
+       //LOG(INFO)<<"waiting for "<<sockcnt;
        struct timeval timeout;
        timeout.tv_sec = usec/TINT_SEC;
        timeout.tv_usec = usec%TINT_SEC;
@@ -56,33 +70,47 @@ int Datagram::Wait (int sockcnt, int* sockets, tint usec) {
                for (int i=0; i<=sockcnt; i++)
                        if (FD_ISSET(sockets[i],&bases))
                                return sockets[i];
-       } else if (sel<0) 
+       } else if (sel<0)
+#ifdef _MSC_VER
+               PLOG(ERROR)<<"select fails" << WSAGetLastError() << "\n";
+#else
                PLOG(ERROR)<<"select fails";
-       return -1;
+#endif
+
+       // Arno: may return 0 when timeout expired
+       return sel;
 }
 
 tint Datagram::Time () {
-       struct timeval t;
-       gettimeofday(&t,NULL);
-       tint ret;
-       ret = t.tv_sec;
-       ret *= 1000000;
-       ret += t.tv_usec;
+       HiResTimeOfDay* tod = HiResTimeOfDay::Instance();
+       tint ret = tod->getTimeUSec();
        //DLOG(INFO)<<"now is "<<ret;
        return now=ret;
 }
 
-int Datagram::Bind (Address addr_) {
+SOCKET Datagram::Bind (Address addr_) {
     struct sockaddr_in addr = addr_;
-       int fd, len = sizeof(struct sockaddr_in), 
-        sndbuf=1<<20, rcvbuf=1<<20;
+       SOCKET fd;
+       int len = sizeof(struct sockaddr_in), sndbuf=1<<20, rcvbuf=1<<20;
        if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
                PLOG(ERROR)<<"socket fails";
         return -1;
     }
+#ifdef _MSC_VER
+       u_long enable = 1;
+       ioctlsocket(fd, FIONBIO, &enable);
+       if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const char *)&sndbuf, sizeof(int)) != 0 ) {
+        PLOG(ERROR)<<"setsockopt fails";
+        return -3;
+    }
+       if ( setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char *)&rcvbuf, sizeof(int)) != 0 ) {
+        PLOG(ERROR)<<"setsockopt2 fails";
+        return -3;
+    }
+#else
        if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
                return -2;
-       if ( setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(int)) < 0 ) {
+       if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(int)) < 0 ) {
         PLOG(ERROR)<<"setsockopt fails";
         return -3;
     }
@@ -90,6 +118,7 @@ int Datagram::Bind (Address addr_) {
         PLOG(ERROR)<<"setsockopt2 fails";
         return -3;
     }
+#endif
     printf("BUFS: %i %i\n",sndbuf,rcvbuf);
     /*memset(&addr, 0, sizeof(struct sockaddr_in));
        addr.sin_family = AF_INET;
@@ -103,14 +132,26 @@ int Datagram::Bind (Address addr_) {
 }
 
 void Datagram::Close (int sock) { // remove from fd_set
+#ifdef _MSC_VER
+       if (closesocket(sock)!=0)
+#else
        if (::close(sock)!=0)
+#endif
                PLOG(ERROR)<<"on closing a socket";
 }
 
 
 std::string sock2str (struct sockaddr_in addr) {
        char ipch[32];
+#ifdef _MSC_VER
+       //Vista only: InetNtop(AF_INET,&(addr.sin_addr),ipch,32);
+       // IPv4 only:
+       struct in_addr inaddr;
+       memcpy(&inaddr, &(addr.sin_addr), sizeof(inaddr));
+       strncpy(ipch, inet_ntoa(inaddr),32);
+#else
        inet_ntop(AF_INET,&(addr.sin_addr),ipch,32);
+#endif
        sprintf(ipch+strlen(ipch),":%i",ntohs(addr.sin_port));
        return std::string(ipch);
 }
@@ -119,7 +160,7 @@ std::string sock2str (struct sockaddr_in addr) {
 std::string Datagram::to_string () const { // TODO: pretty-print P2TP
        std::string addrs = sock2str(addr);
        char hex[MAXDGRAMSZ*2];
-       for(int i=offset; i<length; i++) 
+       for(int i=offset; i<length; i++)
                sprintf(hex+i*2,"%02x",buf[i]);
        std::string hexs(hex+offset*2,(length-offset)*2);
        return addrs + '\t' + hexs;
index ca46bf8..3a56152 100644 (file)
@@ -3,45 +3,49 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/9/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #ifndef DATAGRAM_H
 #define DATAGRAM_H
-#include <stdint.h>
+
+#ifdef _MSC_VER
+    #include "compat/stdint.h"
+    #include <winsock2.h>
+       #include "compat/unixio.h"
+#else
+    typedef int SOCKET;
+    #include <stdint.h>
+    #include <arpa/inet.h>
+    #include <sys/select.h>
+    #include <sys/socket.h>
+    #include <netinet/in.h>
+    #include <unistd.h>
+#endif
 #include <stdlib.h>
 #include <fcntl.h>
-#include <sys/select.h>
 #include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-//#include <sys/mman.h>
 #include <string.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <string>
 #include "hashtree.h"
+#include "compat/hirestimeofday.h"
+
 
 namespace p2tp {
 
-typedef int64_t tint;
-#define TINT_SEC ((tint)1000000)
-#define TINT_MSEC ((tint)1000)
-#define TINT_uSEC ((tint)1)
-#define TINT_NEVER ((tint)0x7fffffffffffffffLL)
 #define MAXDGRAMSZ 1400
+#ifndef _MSC_VER
 #define INVALID_SOCKET -1
-    
-    
+#endif
+
 struct Datagram {
-       
+
     struct Address {
         struct sockaddr_in  addr;
         static uint32_t LOCALHOST;
         void init(uint32_t ipv4=0, uint16_t port=0) {
-            memset(&addr,0,sizeof(struct sockaddr_in)); 
+            memset(&addr,0,sizeof(struct sockaddr_in));
             addr.sin_family = AF_INET;
             addr.sin_port = htons(port);
             addr.sin_addr.s_addr = htonl(ipv4);
@@ -59,35 +63,35 @@ struct Datagram {
         }
         Address(const struct sockaddr_in& address) : addr(address) {}
         operator sockaddr_in () const {return addr;}
-        bool operator == (const Address& b) { 
+        bool operator == (const Address& b) {
             return addr.sin_family==b.addr.sin_family &&
-            addr.sin_port==b.addr.sin_port && 
+            addr.sin_port==b.addr.sin_port &&
             addr.sin_addr.s_addr==b.addr.sin_addr.s_addr;
         }
         bool operator != (const Address& b) { return !(*this==b); }
     };
-    
+
        Address addr;
-       int sock;
+       SOCKET sock;
        int offset, length;
        uint8_t buf[MAXDGRAMSZ*2];
-    
-       static int Bind(Address address);
+
+       static SOCKET Bind(Address address);
        static void Close(int port);
        static tint Time();
-       static int Wait (int sockcnt, int* sockets, tint usec=0);
+       static SOCKET Wait (int sockcnt, SOCKET* sockets, tint usec=0);
        static tint now;
-       
-       Datagram (int socket, const Address addr_) : addr(addr_), offset(0), 
+
+       Datagram (SOCKET socket, const Address addr_) : addr(addr_), offset(0),
                length(0), sock(socket) {}
-       Datagram (int socket) : offset(0), length(0), sock(socket) { 
+       Datagram (SOCKET socket) : offset(0), length(0), sock(socket) {
        }
-       
+
        int space () const { return MAXDGRAMSZ-length; }
        int size() const { return length-offset; }
        std::string str() const { return std::string((char*)buf+offset,size()); }
     const uint8_t* operator * () const { return buf+offset; }
-       
+
        int Push (const uint8_t* data, int l) { // scatter-gather one day
                int toc = l<space() ? l : space();
                memcpy(buf+length,data,toc);
@@ -101,7 +105,7 @@ struct Datagram {
                offset += toc;
                return toc;
        }
-       
+
        int Send ();
        int Recv ();
        const Address& address() const { return addr; }
@@ -129,7 +133,7 @@ struct Datagram {
        void    PushHash (const Sha1Hash& hash) {
                Push(hash.bits, Sha1Hash::SIZE);
        }
-       
+
        uint8_t Pull8() {
                if (size()<1) return 0;
                return buf[offset++];
@@ -159,7 +163,7 @@ struct Datagram {
                return Sha1Hash(false,(char*)buf+offset-Sha1Hash::SIZE);
        }
        //std::string   to_string () const ;
-       
+
 };
 
 std::string sock2str (struct sockaddr_in addr);
index 2eebcc0..007a799 100644 (file)
@@ -3,7 +3,7 @@
  *  p2tp
  *
  *  Created by Victor Grishchenko on 10/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 
index 49d07c7..aeff70c 100644 (file)
@@ -3,7 +3,7 @@
  *  p2tp
  *
  *  Created by Victor Grishchenko on 10/7/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include "p2tp.h"
index 734931f..1001d8e 100644 (file)
@@ -3,7 +3,7 @@
  *  p2tp
  *
  *  Created by Victor Grishchenko on 10/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 
index a45c76f..2f165fa 100644 (file)
@@ -3,7 +3,7 @@
  *  p2tp
  *
  *  Created by Victor Grishchenko on 10/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 
index 18c88d3..aa82018 100644 (file)
@@ -3,14 +3,16 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 
 #include "hashtree.h"
 #include <openssl/sha.h>
 #include <string.h>
+#ifndef _MSC_VER
 #include <sys/mman.h>
+#endif
 #include <sys/stat.h>
 #include <stdlib.h>
 #include <fcntl.h>
@@ -158,7 +160,7 @@ HashTree::hashres_t HashTree::offer (bin pos, const Sha1Hash& hash) {
                return ACCEPT;
        } else
                return REJECT;
-       
+
 }
 
 */
index a25e6af..fe6aac6 100644 (file)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #ifndef P2TP_SHA1_HASH_TREE_H
index c1b4cc0..bbc7aa7 100644 (file)
--- a/p2tp.cpp
+++ b/p2tp.cpp
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 
@@ -32,7 +32,7 @@ int Channel::socket_count = 0;
 
 
 Channel::Channel       (FileTransfer* file, int socket, struct sockaddr_in peer_addr) :
-       file_(file), peer(peer_addr), peer_channel_id(0), 
+       file_(file), peer(peer_addr), peer_channel_id(0),
        socket_(socket) // FIXME
 {
        this->id = channels.size();
@@ -71,8 +71,8 @@ void    p2tp::Shutdown (int sock_des) {
 }
 
 
-void    p2tp::Loop (tint till) { 
-    Channel::Loop(till); 
+void    p2tp::Loop (tint till) {
+    Channel::Loop(till);
 }
 
 
@@ -122,6 +122,5 @@ size_t  p2tp::SeqComplete (int fdes) {
  is mostly zeroed; intialization happens as
  conversation progresses
  </ul>
- <b>Note:</b> 
+ <b>Note:</b>
  */
-
diff --git a/p2tp.h b/p2tp.h
index 8623285..5fc296a 100644 (file)
--- a/p2tp.h
+++ b/p2tp.h
@@ -3,28 +3,28 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
- *     
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
+ *
  */
-/*     
+/*
 
 The P2TP protocol
+
 Messages
+
  HANDSHAKE     00, channelid
  Communicates the channel id of the sender. The
  initial handshake packet also has the root hash
  (a HASH message).
+
  DATA          01, bin_32, buffer
  1K of data.
+
  ACK           02, bin_32
  ACKTS      08, bin_32, timestamp_32
  Confirms successfull delivery of data. Used for
  congestion control, as well.
-  
+
  HINT          03, bin_32
  Practical value of "hints" is to avoid overlap, mostly.
  Hints might be lost in the network or ignored.
@@ -33,24 +33,30 @@ Messages
  is considered to be ignored.
  As peers cant pick randomly kilobyte here and there,
  they send out "long hints" for non-base bins.
+
  HASH          04, bin_32, sha1hash
  SHA1 hash tree hashes for data verification. The
  connection to a fresh peer starts with bootstrapping
  him with peak hashes. Later, before sending out
  any data, a peer sends the necessary uncle hashes.
+
  PEX+/PEX-     05/06, ipv4 addr, port
  Peer exchange messages; reports all connected and
  disconected peers. Might has special meaning (as
  in the case with swarm supervisors).
+
 */
 #ifndef P2TP_H
 #define P2TP_H
+
+#ifdef _MSC_VER
+#include "compat/stdint.h"
+#else
 #include <stdint.h>
+#endif
 #include <vector>
 #include <deque>
+#include <string>
 #include "bin64.h"
 #include "bins.h"
 #include "datagram.h"
@@ -65,38 +71,38 @@ namespace p2tp {
         tintbin() : time(0), bin(bin64_t::NONE) {}
         tintbin(tint time_, bin64_t bin_) : time(time_), bin(bin_) {}
     };
-    
+
        typedef std::deque<tintbin> tbqueue;
     typedef std::deque<bin64_t> binqueue;
     typedef Datagram::Address Address;
 
-       typedef enum { 
-               P2TP_HANDSHAKE = 0, 
-               P2TP_DATA = 1, 
-               P2TP_ACK = 2, 
-               P2TP_ACK_TS = 8, 
-               P2TP_HINT = 3, 
-               P2TP_HASH = 4, 
+       typedef enum {
+               P2TP_HANDSHAKE = 0,
+               P2TP_DATA = 1,
+               P2TP_ACK = 2,
+               P2TP_ACK_TS = 8,
+               P2TP_HINT = 3,
+               P2TP_HASH = 4,
                P2TP_PEX_ADD = 5,
                P2TP_PEX_RM = 6,
                P2TP_MESSAGE_COUNT = 7
        } messageid_t;
-    
+
     class PiecePicker;
     class CongestionController;
     class PeerSelector;
 
-       
+
        class   FileTransfer {
-               
+
     public:
-               
+
                /**     Open/submit/retrieve a file.    */
         FileTransfer(const char *file_name, const Sha1Hash& _root_hash=Sha1Hash::ZERO);
-        
+
                /**     Close everything. */
                ~FileTransfer();
-        
+
         /** Offer a hash; returns true if it verified; false otherwise.
          Once it cannot be verified (no sibling or parent), the hash
          is remembered, while returning false. */
@@ -104,17 +110,17 @@ namespace p2tp {
         /** Offer data; the behavior is the same as with a hash:
             accept or remember or drop. Returns true => ACK is sent. */
         bool            OfferData (bin64_t bin, const uint8_t* data, size_t length);
-        
+
         static FileTransfer* Find (const Sha1Hash& hash);
-               static FileTransfer* file (int fd) { 
-            return fd<files.size() ? files[fd] : NULL; 
+               static FileTransfer* file (int fd) {
+            return fd<files.size() ? files[fd] : NULL;
         }
-        
+
         int             peak_count () const { return peak_count_; }
         bin64_t         peak (int i) const { return peaks_[i]; }
         const Sha1Hash& peak_hash (int i) const { return peak_hashes_[i]; }
         bin64_t         peak_for (bin64_t pos) const;
-        const Sha1Hash& hash (bin64_t pos) const { 
+        const Sha1Hash& hash (bin64_t pos) const {
             assert(pos<sizek_*2);
             return hashes_[pos];
         }
@@ -126,17 +132,16 @@ namespace p2tp {
         uint64_t        complete_kilo () const { return completek_; }
         uint64_t        seq_complete () const { return seq_complete_; }
         bins&           ack_out ()  { return ack_out_; }
-        int             file_descriptor () const { return fd_; } 
+        int             file_descriptor () const { return fd_; }
         PiecePicker*    picker () { return picker_; }
-        
+
         static int instance; // FIXME this smells
-        
+
     private:
 
                static std::vector<FileTransfer*> files;
-        static const char* HASH_FILE_TEMPLATE;
-        static const char* PEAK_FILE_TEMPLATE;
-                       
+               static std::string GetTempFilename(Sha1Hash& root_hash, int instance, std::string postfix);
+
                /**     file descriptor. */
                int                             fd_;
         /** File size, as derived from the hashes. */
@@ -154,6 +159,9 @@ namespace p2tp {
         PiecePicker*    picker_;
                /** File for keeping the Merkle hash tree. */
         int             hashfd_;
+#ifdef _MSC_VER
+        HANDLE                 hashmaphandle_;
+#endif
         /** Merkle hash tree: root */
         Sha1Hash        root_hash_;
         /** Merkle hash tree: peak hashes */
@@ -166,7 +174,7 @@ namespace p2tp {
         bool            dry_run_;
         /** Error encountered */
         char*           error_;
-        
+
     protected:
         void            SetSize(size_t bytes);
         void            Submit();
@@ -183,7 +191,6 @@ namespace p2tp {
         friend int     Open (const char* filename, const Sha1Hash& hash) ;
         friend void    Close (int fd) ;
        };
-       
 
        class CongestionController {
     public:
@@ -198,27 +205,27 @@ namespace p2tp {
         virtual void    OnAckRcvd(const tintbin& tsack) = 0;
                virtual         ~CongestionController() = 0;
        };
-    
+
     class PiecePicker {
     public:
         virtual bin64_t Pick (bins& from, uint8_t layer) = 0;
         virtual void    Received (bin64_t b) = 0;
         virtual void    Snubbed (bin64_t b) = 0;
     };
-    
+
     class PeerSelector {
     public:
         virtual void AddPeer (const Datagram::Address& addr, const Sha1Hash& root) = 0;
         virtual Datagram::Address GetPeer (const Sha1Hash& for_root) = 0;
     };
-    
+
     class DataStorer {
     public:
         DataStorer (const Sha1Hash& id, size_t size);
         virtual size_t    ReadData (bin64_t pos,uint8_t** buf) = 0;
         virtual size_t    WriteData (bin64_t pos, uint8_t* buf, size_t len) = 0;
     };
-       
+
 
        /**     P2TP channel's "control block"; channels loosely correspond to TCP
         connections or FTP sessions; one channel is created for one file
@@ -230,10 +237,10 @@ namespace p2tp {
        public:
                Channel (FileTransfer* file, int socket, struct sockaddr_in peer);
                ~Channel();
-               
+
                static void     Recv (int socket);
         static void Loop (tint till);
-        
+
                void            Recv (Datagram& dgram);
                tint            Send ();
 
@@ -244,7 +251,6 @@ namespace p2tp {
                void            OnHash (Datagram& dgram);
                void            OnPex (Datagram& dgram);
                void            OnHandshake (Datagram& dgram);
-               
                void            AddHandshake (Datagram& dgram);
                bin64_t         AddData (Datagram& dgram);
                void            AddAck (Datagram& dgram);
@@ -255,18 +261,17 @@ namespace p2tp {
         const std::string id_string () const;
         /** A channel is "established" if had already sent and received packets. */
         bool        is_established () { return peer_channel_id && own_id_mentioned; }
-        
+
                static int DecodeID(int scrambled);
                static int EncodeID(int unscrambled);
                static Channel* channel(int i) {
             return i<channels.size()?channels[i]:NULL;
         }
-        
+
         FileTransfer& file() { return *file_; }
-               
-               
+
        private:
-               
+
                /** Channel id: index in the channel array. */
                uint32_t        id;
                /**     Socket address of the peer. */
@@ -292,26 +297,26 @@ namespace p2tp {
                CongestionController    *cc;
         /** For repeats. */
                tint            last_send_time, last_recv_time;
-        
+
         /** Get a rewuest for one packet from the queue of peer's requests. */
         bin64_t                DequeueHint();
         void        CleanStaleHints();
-        
+
         static PeerSelector* peer_selector;
-        
+
                static int      MAX_REORDERING;
                static tint     TIMEOUT;
                static std::vector<Channel*> channels;
         static int      sockets[8];
         static int      socket_count;
                static tint     last_tick;
-        
+
         friend int     Listen (Datagram::Address addr);
         friend void    Shutdown (int sock_des);
         friend void    AddPeer (Datagram::Address address, const Sha1Hash& root);
        };
 
-       
+
 
     /*************** The top-level API ****************/
     /** Start listening a port. Returns socket descriptor. */
@@ -334,16 +339,21 @@ namespace p2tp {
     /** Returns size of the file in bytes, 0 if unknown. Might be rounded up to a kilobyte
         before the transmission is complete. */
     size_t  Size (int fdes);
-    /** Returns the amount of retrieved and verified data, in bytes. 
+    /** Returns the amount of retrieved and verified data, in bytes.
         A 100% complete transmission has Size()==Complete(). */
     size_t  Complete (int fdes);
     /** Returns the number of bytes that are complete sequentially, starting from the
         beginning, till the first not-yet-retrieved packet. */
     size_t  SeqComplete (int fdes);
 
-    
+
        //uint32_t Width (const tbinvec& v);
-}
+
+       void LibraryInit(void);
+       /** Must be called by any client using the library */
+
+
+} // namespace end
 
 #define RETLOG(str) { LOG(WARNING)<<str; return; }
 
index 4c1552a..87627e9 100644 (file)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 
index d56b2e4..f21ff8f 100644 (file)
--- a/sbit.cpp
+++ b/sbit.cpp
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 4/1/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include "sbit.h"
diff --git a/sbit.h b/sbit.h
index edb84a6..cb306db 100644 (file)
--- a/sbit.h
+++ b/sbit.h
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/28/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #ifndef SERP_SBIT_H
index 58c7fdd..57beea7 100644 (file)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include <algorithm>
index 31cf098..f7f8d0f 100644 (file)
@@ -1,58 +1,81 @@
-env = Environment(CPPPATH = '.',CXXFLAGS="-g")
+import sys
+
+Import("DEBUG")
+Import("env")
+Import("libs")
+Import("libpath")
+
+cpppath = env["CPPPATH"]
+libs = ['p2tp'] + libs  # order is important, crypto needs to be last
+
+if sys.platform == "win32":
+    cpppath = ".."
+    libpath += '..;'
+    if DEBUG:
+        env.Append(CXXFLAGS="/Zi /Yd /MTd")
+else:
+    cpppath = cpppath + ':..'
+    libpath += ':..'
+    if DEBUG:
+        env.Append(CXXFLAGS="-g")
+
+print "tests: libpath is",libpath
 
 env.Program( 
     target='binstest2',
     source=['binstest2.cpp'],
-    CPPPATH=['..'],
-    LIBS=['p2tp','stdc++','gtest','glog'],
-    LIBPATH='..' )
+    CPPPATH=cpppath,
+    LIBS=libs,
+    LIBPATH=libpath )
 
 env.Program( 
     target='dgramtest',
     source=['dgramtest.cpp'],
-    CPPPATH=['..'],
-    LIBS=['p2tp','stdc++','gtest','glog'],
-    LIBPATH='..' )
+    CPPPATH=cpppath,
+    LIBS=libs,
+    LIBPATH=libpath )
 
 env.Program( 
     target='hashtest',
     source=['hashtest.cpp'],
-    CPPPATH=['..'],
-    LIBS=['p2tp','stdc++','gtest','glog','crypto'],
-    LIBPATH='..' )
+    CPPPATH=cpppath,
+    LIBS=libs,
+    LIBPATH=libpath )
 
 env.Program( 
     target='ledbattest',
     source=['ledbattest.cpp'],
-    CPPPATH=['..'],
-    LIBS=['p2tp','stdc++','gtest','glog','crypto'],
-    LIBPATH='..' )
+    CPPPATH=cpppath,
+    LIBS=libs,
+    LIBPATH=libpath )
 
-env.Program( 
-    target='ledbattest2',
-    source=['ledbattest2.cpp'],
-    CPPPATH=['..'],
-    LIBS=['p2tp','stdc++','gtest','glog','crypto'],
-    LIBPATH='..' )
+
+if sys.platform != "win32":
+    # Arno: Needs getopt
+    env.Program( 
+        target='ledbattest2',
+        source=['ledbattest2.cpp'],
+        CPPPATH=cpppath,
+        LIBS=libs,
+        LIBPATH=libpath )
 
 env.Program( 
     target='freemap',
     source=['freemap.cpp'],
-    CPPPATH=['..'],
-    LIBS=['p2tp','stdc++','gtest','glog'],
-    LIBPATH='..' )
+    CPPPATH=cpppath,
+    LIBS=libs,
+    LIBPATH=libpath )
 
 env.Program( 
     target='bin64test',
     source=['bin64test.cpp'],
-    CPPPATH=['..'],
-    LIBS=['p2tp','gtest'],
-    LIBPATH='..' )
+    CPPPATH=cpppath,
+    LIBS=libs,
+    LIBPATH=libpath )
 
 env.Program( 
     target='transfertest',
     source=['transfertest.cpp'],
-    CPPPATH=['..'],
-    LIBS=['p2tp','gtest'],
-    LIBPATH='..' )
-
+    CPPPATH=cpppath,
+    LIBS=libs,
+    LIBPATH=libpath )
index 7f3c44d..157c447 100644 (file)
@@ -3,7 +3,7 @@
  *  bin++
  *
  *  Created by Victor Grishchenko on 3/9/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include "bin64.h"
@@ -36,7 +36,7 @@ TEST(Bin64Test,Navigation) {
 }
 
 TEST(Bin64Test,Overflows) {
-    
+
     /*EXPECT_EQ(bin64_t::NONE.parent(),bin64_t::NONE);
     EXPECT_EQ(bin64_t::NONE.left(),bin64_t::NONE);
     EXPECT_EQ(bin64_t::NONE.right(),bin64_t::NONE);
@@ -46,7 +46,7 @@ TEST(Bin64Test,Overflows) {
 }
 
 TEST(Bin64Test, Advanced) {
-    
+
     EXPECT_EQ(4,bin64_t(2,3).width());
     EXPECT_FALSE(bin64_t(1,1234).is_base());
     EXPECT_TRUE(bin64_t(0,12345).is_base());
@@ -57,7 +57,7 @@ TEST(Bin64Test, Advanced) {
     EXPECT_EQ(bin64_t(2,0),peaks[0]);
     EXPECT_EQ(bin64_t(1,2),peaks[1]);
     EXPECT_EQ(bin64_t(0,6),peaks[2]);
-    
+
 }
 
 TEST(Bin64Test, Iteration) {
@@ -85,8 +85,8 @@ TEST(Bin64Test, Bits) {
 }
 
 int main (int argc, char** argv) {
-       
+
        testing::InitGoogleTest(&argc, argv);
        return RUN_ALL_TESTS();
-       
+
 }
index caa51b3..91eb1f6 100644 (file)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/22/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include <time.h>
index 9d76467..a3fadfb 100755 (executable)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/22/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include <time.h>
index 7f6dadc..cb5aeee 100644 (file)
@@ -3,7 +3,7 @@
  *  bin++
  *
  *  Created by Victor Grishchenko on 3/9/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include "bin.h"
index 769fec2..cec343c 100644 (file)
@@ -3,7 +3,7 @@
  *  p2tp
  *
  *  Created by Victor Grishchenko on 7/13/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include <stdint.h>
index 9cecd7a..258ccd2 100644 (file)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/19/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 
index 87d4313..4a58d8b 100644 (file)
@@ -3,18 +3,19 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/13/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include <gtest/gtest.h>
 #include <glog/logging.h>
 #include "datagram.h"
+#include "p2tp.h" // Arno: for LibraryInit
 
 using namespace p2tp;
 
 
-TEST(Datagram, BinaryTest) {   
-       int socket = Datagram::Bind(7001);
+TEST(Datagram, BinaryTest) {
+       SOCKET socket = Datagram::Bind(7001);
        ASSERT_TRUE(socket>0);
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
@@ -39,9 +40,11 @@ TEST(Datagram, BinaryTest) {
        EXPECT_STREQ("74657874ababcdabcdef01000abcdefabcdeff",buf);
        int datalen = strlen(text)+1+2+4+8;
        ASSERT_EQ(datalen,d.Send());
-    int socks[1] = {socket};
-       ASSERT_EQ (socket, Datagram::Wait(1,socks));
-       Datagram rcv(socket);
+    SOCKET socks[1] = {socket};
+    // Arno: timeout 0 gives undeterministic behaviour on win32
+       SOCKET waitsocket = Datagram::Wait(1,socks,1000000);
+       ASSERT_EQ(socket,waitsocket);
+       Datagram rcv(waitsocket);
        ASSERT_EQ(datalen,rcv.Recv());
        char* rbuf;
        int pl = rcv.Pull((uint8_t**)&rbuf,strlen(text));
@@ -71,26 +74,29 @@ TEST(Datagram,TwoPortTest) {
        addr2.sin_family = AF_INET;
        addr2.sin_port = htons(10002);
        addr2.sin_addr.s_addr = htonl(INADDR_LOOPBACK);*/
-       
+
        Datagram send(sock1,Datagram::Address(10002));
        send.Push32(1234);
        send.Send();
-       
-    int socks[2] = {sock1,sock2};
-       EXPECT_EQ(sock2,Datagram::Wait(2,socks));
+
+    SOCKET socks[2] = {sock1,sock2};
+    // Arno: timeout 0 gives undeterministic behaviour on win32
+       EXPECT_EQ(sock2,Datagram::Wait(2,socks,1000000));
        Datagram recv(sock2);
        recv.Recv();
        uint32_t test = recv.Pull32();
        ASSERT_EQ(1234,test);
-       
+
        Datagram::Close(sock1);
        Datagram::Close(sock2);
 }
 
 int main (int argc, char** argv) {
-       
+
+       p2tp::LibraryInit();
+
        testing::InitGoogleTest(&argc, argv);
     google::InitGoogleLogging(argv[0]);
        return RUN_ALL_TESTS();
-       
+
 }
index f98b33a..f368d12 100755 (executable)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/22/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include <time.h>
 #include <set>
 #include "bins.h"
 
+#ifdef _MSC_VER
+       #define RANDOM  rand
+#else
+       #define RANDOM  random
+#endif
+
 int bins_stripe_count (bins& b) {
     int stripe_count;
     uint64_t * stripes = b.get_stripes(stripe_count);
@@ -19,7 +25,7 @@ int bins_stripe_count (bins& b) {
 }
 
 uint8_t rand_norm (uint8_t lim) {
-    long rnd = random() & ((1<<lim)-1);
+    long rnd = RANDOM() & ((1<<lim)-1);
     uint8_t bits = 0;
     while (rnd) {
         bits += rnd&1;
index ecb71f5..a0d16ae 100644 (file)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/12/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include <fcntl.h>
index 3155b40..ee6302f 100644 (file)
@@ -39,8 +39,8 @@ TEST(Datagram,LedbatTest) {
     tint last_sec = 0;
     int sec_ackd = 0;
 
-    int send_sock = Datagram::Bind(10001); // bind sending socket
-    int ack_sock = Datagram::Bind(10002);  // bind receiving socket
+    SOCKET send_sock = Datagram::Bind(10001); // bind sending socket
+    SOCKET ack_sock = Datagram::Bind(10002);  // bind receiving socket
     struct sockaddr_in send_to, ack_to;
     send_to.sin_family = AF_INET;
     send_to.sin_port = htons(10002);
@@ -49,8 +49,8 @@ TEST(Datagram,LedbatTest) {
     ack_to.sin_port = htons(10001);
     ack_to.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
     uint8_t* garbage = (uint8_t*) malloc(1024);
-    int socks[2] = {send_sock,ack_sock};
-    int sock2read;
+    SOCKET socks[2] = {send_sock,ack_sock};
+    SOCKET sock2read;
     tint wait_time = 100*TINT_MSEC;
 
     while (sock2read = Datagram::Wait(2,socks,wait_time)) {
@@ -67,7 +67,7 @@ TEST(Datagram,LedbatTest) {
             fprintf(stderr,"%lli rcvd%i\n",now/TINT_SEC,seq);
             // TODO: peer cwnd !!!
             continue;
-        } 
+        }
         if (sock2read==send_sock) {        // process an acknowledgement
             Datagram ack(send_sock);
             ack.Recv();
@@ -168,6 +168,9 @@ TEST(Datagram,LedbatTest) {
 
 int main (int argc, char** argv) {
     printf("Warning: use the script to set up dummynet!\n");
+
+    p2tp::LibraryInit();
+
     testing::InitGoogleTest(&argc, argv);
     google::InitGoogleLogging(argv[0]);
     return RUN_ALL_TESTS();
index 235d956..0acded2 100644 (file)
@@ -1,8 +1,13 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
+#ifdef _MSC_VER
+       #include "compat/stdint.h"
+    #include <winsock2.h>
+#else
+   #include <sys/socket.h>
+   #include <netinet/in.h>
+   #include <arpa/inet.h>
+#endif
 #include <vector>
 #include <deque>
 #include "datagram.h"
@@ -74,7 +79,7 @@ TEST(Datagram,LedbatTest) {
             fprintf(stderr,"%lli rcvd%i\n",now/TINT_SEC,seq);
             // TODO: peer cwnd !!!
             continue;
-        } 
+        }
         if (sock2read==send_sock) {        // process an acknowledgement
             Datagram ack(send_sock);
             ack.Recv();
index 1c80845..0f77b1b 100644 (file)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/19/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 
index 4251d5a..8877773 100644 (file)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 4/1/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 
index c321ac9..f6d22bd 100644 (file)
@@ -3,7 +3,7 @@
  *  serp++
  *
  *  Created by Victor Grishchenko on 3/9/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include "bin.h"
index 7ae096c..e4c4b1b 100644 (file)
@@ -3,11 +3,16 @@
  *  p2tp
  *
  *  Created by Victor Grishchenko on 10/7/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
 #include <gtest/gtest.h>
+#include <glog/logging.h>
 #include "p2tp.h"
+#include "compat/util.h"
+#ifdef _MSC_VER
+#include "compat/unixio.h"
+#endif
 
 using namespace p2tp;
 
@@ -29,7 +34,7 @@ TEST(TransferTest,TransferFile) {
         ROOT = Sha1Hash(ROOT,Sha1Hash::ZERO);
         //printf("m %lli %s\n",(uint64_t)pos.parent(),ROOT.hex().c_str());
     }
-    
+
     // submit a new file
     FileTransfer* seed = new FileTransfer(BTF);
     EXPECT_TRUE(A==seed->hash(0));
@@ -43,7 +48,7 @@ TEST(TransferTest,TransferFile) {
     EXPECT_EQ(5,seed->size_kilo());
     EXPECT_EQ(4100,seed->complete());
     EXPECT_EQ(4100,seed->seq_complete());
-    
+
     // retrieve it
     unlink("copy");
     FileTransfer::instance = 1;
@@ -84,7 +89,7 @@ TEST(TransferTest,TransferFile) {
     EXPECT_EQ(5,leech->size_kilo());
     EXPECT_EQ(4100,leech->complete());
     EXPECT_EQ(4100,leech->seq_complete());
-    
+
 }
 /*
  FIXME
@@ -92,18 +97,26 @@ TEST(TransferTest,TransferFile) {
  */
 
 int main (int argc, char** argv) {
-    
-    unlink("/tmp/.70196e6065a42835b1f08227ac3e2fb419cf78c8.0.hashes");
-    unlink("/tmp/.70196e6065a42835b1f08227ac3e2fb419cf78c8.0.peaks");
-    unlink("/tmp/.70196e6065a42835b1f08227ac3e2fb419cf78c8.1.hashes");
-    unlink("/tmp/.70196e6065a42835b1f08227ac3e2fb419cf78c8.1.peaks");
-    unlink("/tmp/.70196e6065a42835b1f08227ac3e2fb419cf78c8.2.hashes");
-    unlink("/tmp/.70196e6065a42835b1f08227ac3e2fb419cf78c8.2.peaks");
-    
+
+       google::InitGoogleLogging(argv[0]);
+
+       std::string tempdir = gettmpdir();
+    unlink((tempdir + std::string(".70196e6065a42835b1f08227ac3e2fb419cf78c8.0.hashes")).c_str());
+    unlink((tempdir + std::string(".70196e6065a42835b1f08227ac3e2fb419cf78c8.0.peaks")).c_str());
+    unlink((tempdir + std::string(".70196e6065a42835b1f08227ac3e2fb419cf78c8.1.hashes")).c_str());
+    unlink((tempdir + std::string(".70196e6065a42835b1f08227ac3e2fb419cf78c8.1.peaks")).c_str());
+    unlink((tempdir + std::string(".70196e6065a42835b1f08227ac3e2fb419cf78c8.2.hashes")).c_str());
+    unlink((tempdir + std::string(".70196e6065a42835b1f08227ac3e2fb419cf78c8.2.peaks")).c_str());
+
     unlink(BTF);
     unlink("copy");
-        
+
        int f = open(BTF,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+       if (f < 0)
+       {
+               PLOG(FATAL)<< "Error opening " << BTF << "\n";
+               return -1;
+       }
     uint8_t buf[1024];
     memset(buf,'A',1024);
     A = Sha1Hash(buf,1024);
@@ -121,9 +134,9 @@ int main (int argc, char** argv) {
     E = Sha1Hash(buf,4);
     write(f,buf,4);
        close(f);
-    
+
        testing::InitGoogleTest(&argc, argv);
        int ret = RUN_ALL_TESTS();
-    
+
     return ret;
 }
index 59900e5..bb6cdb7 100644 (file)
@@ -3,18 +3,24 @@
  *  p2tp
  *
  *  Created by Victor Grishchenko on 10/6/09.
- *  Copyright 2009 Delft Technical University. All rights reserved.
+ *  Copyright 2009 Delft University of Technology. All rights reserved.
  *
  */
+#ifdef _MSC_VER
+#include "compat/unixio.h"
+#else
 #include <sys/mman.h>
+#endif
 #include <errno.h>
+#include <string>
+#include <sstream>
 #include "p2tp.h"
+#include "compat/util.h"
 
 using namespace p2tp;
 
 std::vector<FileTransfer*> FileTransfer::files(20);
-const char* FileTransfer::HASH_FILE_TEMPLATE = "/tmp/.%s.%i.hashes";
-const char* FileTransfer::PEAK_FILE_TEMPLATE = "/tmp/.%s.%i.peaks";
+
 int FileTransfer::instance = 0;
 #define BINHASHSIZE (sizeof(bin64_t)+sizeof(Sha1Hash))
 
@@ -23,7 +29,7 @@ int FileTransfer::instance = 0;
 // FIXME: separate Bootstrap() and Download(), then Size(), Progress(), SeqProgress()
 
 FileTransfer::FileTransfer (const char* filename, const Sha1Hash& _root_hash) :
-    root_hash_(_root_hash), fd_(0), hashfd_(0), dry_run_(false), 
+    root_hash_(_root_hash), fd_(0), hashfd_(0), dry_run_(false),
     peak_count_(0), hashes_(NULL), error_(NULL), size_(0), sizek_(0),
     complete_(0), completek_(0), seq_complete_(0)
 {
@@ -42,9 +48,8 @@ FileTransfer::FileTransfer (const char* filename, const Sha1Hash& _root_hash) :
 
 
 void FileTransfer::LoadPeaks () {
-    char file_name[1024];
-    sprintf(file_name,PEAK_FILE_TEMPLATE,root_hash().hex().c_str(),instance);
-    int peakfd = open(file_name,O_RDONLY);
+    std::string file_name = GetTempFilename(root_hash_,instance,std::string(".peaks"));
+    int peakfd = open(file_name.c_str(),O_RDONLY,0);
     if (peakfd<0)
         return;
     bin64_t peak;
@@ -79,9 +84,8 @@ void            FileTransfer::RecoverProgress () {
 
 
 void    FileTransfer::SavePeaks () {
-    char file_name[1024];
-    sprintf(file_name,PEAK_FILE_TEMPLATE,root_hash().hex().c_str(),instance);
-    int peakfd = open(file_name,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+    std::string file_name = GetTempFilename(root_hash_,instance,std::string(".peaks"));
+    int peakfd = open(file_name.c_str(),O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
     for(int i=0; i<peak_count(); i++) {
         write(peakfd,&(peaks_[i]),sizeof(bin64_t));
         write(peakfd,*peak_hashes_[i],Sha1Hash::SIZE);
@@ -94,24 +98,44 @@ void FileTransfer::SetSize (size_t bytes) { // peaks/root must be already set
     size_ = bytes;
     completek_ = complete_ = seq_complete_ = 0;
        sizek_ = (size_>>10) + ((size_&1023) ? 1 : 0);
-    
-    char file_name[1024];
+
        struct stat st;
        fstat(fd_, &st);
     if (st.st_size!=bytes)
         if (ftruncate(fd_, bytes))
             return; // remain in the 0-state
     // mmap the hash file into memory
-    sprintf(file_name,HASH_FILE_TEMPLATE,root_hash().hex().c_str(),instance);
-       hashfd_ = open(file_name,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
-    size_t expected_size = Sha1Hash::SIZE * sizek_ * 2;
+    std::string file_name = GetTempFilename(root_hash_,instance,std::string(".hashes"));
+       hashfd_ = open(file_name.c_str(),O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+    size_t expected_size_ = Sha1Hash::SIZE * sizek_ * 2;
        struct stat hash_file_st;
        fstat(hashfd_, &hash_file_st);
-    if ( hash_file_st.st_size != expected_size )
-        ftruncate(hashfd_, expected_size);
-    hashes_ = (Sha1Hash*) mmap (NULL, expected_size, PROT_READ|PROT_WRITE, 
+    if ( hash_file_st.st_size != expected_size_ )
+        ftruncate(hashfd_, expected_size_);
+#ifdef _MSC_VER
+    HANDLE hashhandle = (HANDLE)_get_osfhandle(hashfd_);
+    hashmaphandle_ = CreateFileMapping(hashhandle,
+                                             NULL,
+                                             PAGE_READWRITE,
+                                             0,
+                                             0,
+                                             NULL);
+       if (hashmaphandle_ != NULL)
+       {
+               hashes_ = (Sha1Hash*)MapViewOfFile(hashmaphandle_,
+                                                        FILE_MAP_WRITE,
+                                                    0,
+                                                    0,
+                                                    0);
+
+       }
+       if (hashmaphandle_ == NULL || hashes_ == NULL)
+#else
+    hashes_ = (Sha1Hash*) mmap (NULL, expected_size, PROT_READ|PROT_WRITE,
                                MAP_SHARED, hashfd_, 0);
-    if (hashes_==MAP_FAILED) {
+    if (hashes_==MAP_FAILED)
+#endif
+    {
         hashes_ = NULL;
         size_ = sizek_ = complete_ = completek_ = seq_complete_ = 0;
         error_ = strerror(errno); // FIXME dprintf()
@@ -120,7 +144,7 @@ void FileTransfer::SetSize (size_t bytes) { // peaks/root must be already set
     }
     for(int i=0; i<peak_count_; i++)
         hashes_[peaks_[i]] = peak_hashes_[i];
-}  
+}
 
 
 void            FileTransfer::Submit () {
@@ -131,7 +155,7 @@ void            FileTransfer::Submit () {
     hashes_ = (Sha1Hash*) malloc(Sha1Hash::SIZE*sizek_*2);
     peak_count_ = bin64_t::peaks(sizek_,peaks_);
     for (int p=0; p<peak_count_; p++) {
-        for(bin64_t b=peaks_[p].left_foot(); b.within(peaks_[p]); b=b.next_dfsio(0)) 
+        for(bin64_t b=peaks_[p].left_foot(); b.within(peaks_[p]); b=b.next_dfsio(0))
             if (b.is_base()) {
                 uint8_t kilo[1<<10];
                 size_t rd = pread(fd_,kilo,1<<10,b.base_offset()<<10);
@@ -160,7 +184,7 @@ bin64_t         FileTransfer::peak_for (bin64_t pos) const {
 }
 
 
-void            FileTransfer::OfferHash (bin64_t pos, const Sha1Hash& hash) {    
+void            FileTransfer::OfferHash (bin64_t pos, const Sha1Hash& hash) {
        if (!size_)  // only peak hashes are accepted at this point
                return OfferPeak(pos,hash);
     int pi=0;
@@ -193,8 +217,8 @@ bool            FileTransfer::OfferData (bin64_t pos, const uint8_t* data, size_
     bin64_t peak = peak_for(pos);
     if (peak==bin64_t::NONE)
         return false;
-    
-    Sha1Hash hash(data,length);       
+
+    Sha1Hash hash(data,length);
     bin64_t p = pos;
     while ( p!=peak && ack_out_.get(p)==bins::EMPTY ) {
         hashes_[p] = hash;
@@ -203,7 +227,7 @@ bool            FileTransfer::OfferData (bin64_t pos, const uint8_t* data, size_
     }
     if (hash!=hashes_[p])
         return false;
-    
+
     //printf("g %lli %s\n",(uint64_t)pos,hash.hex().c_str());
        // walk to the nearest proven hash   FIXME 0-layer peak
     ack_out_.set(pos,bins::FILLED);
@@ -249,7 +273,7 @@ void            FileTransfer::OfferPeak (bin64_t pos, const Sha1Hash& hash) {
     assert(!size_);
     if (peak_count_) {
         bin64_t last_peak = peaks_[peak_count_-1];
-        if ( pos.layer()>=last_peak.layer() || 
+        if ( pos.layer()>=last_peak.layer() ||
              pos.base_offset()!=last_peak.base_offset()+last_peak.width() )
             peak_count_ = 0;
     }
@@ -265,14 +289,20 @@ void            FileTransfer::OfferPeak (bin64_t pos, const Sha1Hash& hash) {
 }
 
 
-FileTransfer::~FileTransfer () {
+FileTransfer::~FileTransfer ()
+{
+#ifdef _MSC_VER
+       UnmapViewOfFile(hashes_);
+       CloseHandle(hashmaphandle_);
+#else
     munmap(hashes_,sizek_*2*Sha1Hash::SIZE);
     close(hashfd_);
     close(fd_);
     files[fd_] = NULL;
+#endif
 }
 
-                           
+
 FileTransfer* FileTransfer::Find (const Sha1Hash& root_hash) {
     for(int i=0; i<files.size(); i++)
         if (files[i] && files[i]->root_hash_==root_hash)
@@ -281,6 +311,18 @@ FileTransfer* FileTransfer::Find (const Sha1Hash& root_hash) {
 }
 
 
+
+std::string FileTransfer::GetTempFilename(Sha1Hash& root_hash, int instance, std::string postfix)
+{
+       std::string tempfile = gettmpdir();
+       std::stringstream ss;
+       ss << instance;
+       tempfile += std::string(".") + root_hash.hex() + std::string(".") + ss.str() + postfix;
+       return tempfile;
+}
+
+
+
 int      p2tp::Open (const char* filename, const Sha1Hash& hash) {
     FileTransfer* ft = new FileTransfer(filename, hash);
     int fdes = ft->file_descriptor();
@@ -306,7 +348,7 @@ int      p2tp::Open (const char* filename, const Sha1Hash& hash) {
  break;
  x = x.left();
  }
+
  if (x.layer()==10) {
  if (recheck_data) {
  uint8_t data[1024];
@@ -319,16 +361,16 @@ int      p2tp::Open (const char* filename, const Sha1Hash& hash) {
  ack_out->set(x,bins::FILLED);
  }
  }
+
  while (x.is_right() && x!=peaks[i])
  x = x.parent();
  x = x.sibling();
  } while (x!=end);
  }
+
+
+
+
  // open file
  if ( hash_file_st.st_size < (sizeof(bin64_t)+Sha1Hash::SIZE)*64 )
  return;
@@ -354,6 +396,6 @@ int      p2tp::Open (const char* filename, const Sha1Hash& hash) {
  }
  if (!size)
  return;
+
+
  */