add .gitignore
[swift-upb.git] / swift.h
diff --git a/swift.h b/swift.h
index dd74f64..5472a94 100644 (file)
--- a/swift.h
+++ b/swift.h
@@ -20,12 +20,12 @@ Messages
  DATA        01, bin_32, buffer
  1K of data.
 
- ACK        02, bin_32
ACKTS      08, bin_32, timestamp_32
+ ACK        02, bin_32, timestamp_32
HAVE       03, bin_32
  Confirms successfull delivery of data. Used for
  congestion control, as well.
 
- HINT        03, bin_32
+ HINT        08, bin_32
  Practical value of "hints" is to avoid overlap, mostly.
  Hints might be lost in the network or ignored.
  Peer might send out data without a hint.
@@ -49,11 +49,6 @@ Messages
 #ifndef SWIFT_H
 #define SWIFT_H
 
-#ifdef _MSC_VER
-#include "compat/stdint.h"
-#else
-#include <stdint.h>
-#endif
 #include <deque>
 #include <vector>
 #include <algorithm>
@@ -66,9 +61,9 @@ Messages
 namespace swift {
 
     #define NOW Datagram::now
-    
+
     /** tintbin is basically a pair<tint,bin64_t> plus some nice operators.
-        Most frequently used in different queues (acknowledgements, requests, 
+        Most frequently used in different queues (acknowledgements, requests,
         etc). */
     struct tintbin {
         tint    time;
@@ -77,7 +72,7 @@ namespace swift {
         tintbin() : time(TINT_NEVER), bin(bin64_t::NONE) {}
         tintbin(tint time_, bin64_t bin_) : time(time_), bin(bin_) {}
         tintbin(bin64_t bin_) : time(NOW), bin(bin_) {}
-        bool operator < (const tintbin& b) const 
+        bool operator < (const tintbin& b) const
             { return time > b.time; }
         bool operator == (const tintbin& b) const
             { return time==b.time && bin==b.bin; }
@@ -115,13 +110,12 @@ namespace swift {
         SWIFT_HANDSHAKE = 0,
         SWIFT_DATA = 1,
         SWIFT_ACK = 2,
-        SWIFT_TS = 8,
-        SWIFT_HINT = 3,
+        SWIFT_HAVE = 3,
         SWIFT_HASH = 4,
         SWIFT_PEX_ADD = 5,
         SWIFT_PEX_RM = 6,
         SWIFT_SIGNED_HASH = 7,
-        SWIFT_MSGTYPE_SENT = 8,
+        SWIFT_HINT = 8,
         SWIFT_MSGTYPE_RCVD = 9,
         SWIFT_MESSAGE_COUNT = 10
     } messageid_t;
@@ -129,6 +123,7 @@ namespace swift {
     class PiecePicker;
     class CongestionController;
     class PeerSelector;
+    typedef void (*ProgressCallback) (int transfer, bin64_t bin);
 
 
     /** A class representing single file transfer. */
@@ -136,8 +131,8 @@ namespace swift {
 
     public:
 
-        /** A constructor. Open/submit/retrieve a file. 
-         *  @param file_name    the name of the file 
+        /** A constructor. Open/submit/retrieve a file.
+         *  @param file_name    the name of the file
          *  @param root_hash    the root hash of the file; zero hash if the file
                                 is newly submitted */
         FileTransfer(const char *file_name, const Sha1Hash& root_hash=Sha1Hash::ZERO);
@@ -189,9 +184,14 @@ namespace swift {
 
         /** Messages we are accepting.    */
         uint64_t        cap_out_;
-        
+
         tint            init_time_;
 
+        #define SWFT_MAX_TRANSFER_CB 8
+        ProgressCallback callbacks[SWFT_MAX_TRANSFER_CB];
+        uint8_t         cb_agg[SWFT_MAX_TRANSFER_CB];
+        int             cb_installed;
+
     public:
         void            OnDataIn (bin64_t pos);
         void            OnPexIn (const Address& addr);
@@ -203,6 +203,9 @@ namespace swift {
         friend uint64_t  SeqComplete (int fdes);
         friend int     Open (const char* filename, const Sha1Hash& hash) ;
         friend void    Close (int fd) ;
+        friend void AddProgressCallback (int transfer,ProgressCallback cb,uint8_t agg);
+        friend void RemoveProgressCallback (int transfer,ProgressCallback cb);
+        friend void ExternallyRetrieved (int transfer,bin64_t piece);
     };
 
 
@@ -214,11 +217,12 @@ namespace swift {
     public:
         virtual void Randomize (uint64_t twist) = 0;
         /** The piece picking method itself.
-         *  @param  offered     the daata acknowledged by the peer 
+         *  @param  offered     the daata acknowledged by the peer
          *  @param  max_width   maximum number of packets to ask for
          *  @param  expires     (not used currently) when to consider request expired
          *  @return             the bin number to request */
         virtual bin64_t Pick (binmap_t& offered, uint64_t max_width, tint expires) = 0;
+        virtual void LimitRange (bin64_t range) = 0;
         virtual ~PiecePicker() {}
     };
 
@@ -243,11 +247,11 @@ namespace swift {
         being transferred between two peers. As we don't need buffers and
         lots of other TCP stuff, sizeof(Channel+members) must be below 1K.
         Normally, API users do not deal with this class. */
-    class Channel {  
+    class Channel {
     public:
-        Channel    (FileTransfer* file, int socket=-1, Address peer=Address());
+        Channel    (FileTransfer* file, int socket=INVALID_SOCKET, Address peer=Address());
         ~Channel();
-        
+
         typedef enum {
             KEEP_ALIVE_CONTROL,
             PING_PONG_CONTROL,
@@ -256,11 +260,10 @@ namespace swift {
             LEDBAT_CONTROL,
             CLOSE_CONTROL
         } send_control_t;
-        
+
         static const char* SEND_CONTROL_MODES[];
 
-        static Channel*
-                    RecvDatagram (int socket);
+        static void RecvDatagram (SOCKET socket);
         static void Loop (tint till);
 
         void        Recv (Datagram& dgram);
@@ -268,7 +271,7 @@ namespace swift {
         void        Close ();
 
         void        OnAck (Datagram& dgram);
-        void        OnTs (Datagram& dgram);
+        void        OnHave (Datagram& dgram);
         bin64_t     OnData (Datagram& dgram);
         void        OnHint (Datagram& dgram);
         void        OnHash (Datagram& dgram);
@@ -277,7 +280,7 @@ namespace swift {
         void        AddHandshake (Datagram& dgram);
         bin64_t     AddData (Datagram& dgram);
         void        AddAck (Datagram& dgram);
-        void        AddTs (Datagram& dgram);
+        void        AddHave (Datagram& dgram);
         void        AddHint (Datagram& dgram);
         void        AddUncleHashes (Datagram& dgram, bin64_t pos);
         void        AddPeakHashes (Datagram& dgram);
@@ -292,7 +295,7 @@ namespace swift {
         tint        SlowStartNextSendTime ();
         tint        AimdNextSendTime ();
         tint        LedbatNextSendTime ();
-        
+
         static int  MAX_REORDERING;
         static tint TIMEOUT;
         static tint MIN_DEV;
@@ -302,7 +305,8 @@ namespace swift {
         static tint LEDBAT_DELAY_BIN;
         static bool SELF_CONN_OK;
         static tint MAX_POSSIBLE_RTT;
-        
+        static FILE* debug_file;
+
         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_; }
@@ -310,17 +314,18 @@ namespace swift {
         HashTree&   file () { return transfer_->file(); }
         const Address& peer() const { return peer_; }
         tint ack_timeout () {
-            return std::min(30*TINT_SEC,rtt_avg_ + std::max(dev_avg_,MIN_DEV)*4);
+                       tint dev = dev_avg_ < MIN_DEV ? MIN_DEV : dev_avg_;
+                       tint tmo = rtt_avg_ + dev * 4;
+                       return tmo < 30*TINT_SEC ? tmo : 30*TINT_SEC;
         }
         uint32_t    id () const { return id_; }
-        
+
         static int  DecodeID(int scrambled);
         static int  EncodeID(int unscrambled);
         static Channel* channel(int i) {
             return i<channels.size()?channels[i]:NULL;
         }
         static void CloseTransfer (FileTransfer* trans);
-        static SOCKET default_socket() { return sockets[0]; }
 
     protected:
         /** Channel id: index in the channel array. */
@@ -345,7 +350,7 @@ namespace swift {
         tbqueue     data_out_tmo_;
         bin64_t     data_out_cap_;
         /** Index in the history array. */
-        binmap_t        ack_out_;
+        binmap_t        have_out_;
         /**    Transmit schedule: in most cases filled with the peer's hints */
         tbqueue     hint_in_;
         /** Hints sent (to detect and reschedule ignored hints). */
@@ -365,7 +370,6 @@ namespace swift {
         tint        last_data_in_time_;
         tint        last_loss_time_;
         tint        next_send_time_;
-        tint        peer_send_time_;
         /** Congestion window; TODO: int, bytes. */
         float       cwnd_;
         /** Data sending interval. */
@@ -393,17 +397,16 @@ namespace swift {
         }
         /** Get a request for one packet from the queue of peer's requests. */
         bin64_t     DequeueHint();
-        void        CleanDataOut (bin64_t acks_pos=bin64_t::NONE);
+        bin64_t     ImposeHint();
+        void        TimeoutDataOut ();
         void        CleanStaleHintOut();
         void        CleanHintOut(bin64_t pos);
         void        Reschedule();
 
         static PeerSelector* peer_selector;
 
-        static SOCKET   sockets[8];
-        static int      socket_count;
         static tint     last_tick;
-        static tbheap   send_queue;        
+        static tbheap   send_queue;
 
         static Address  tracker;
         static std::vector<Channel*> channels;
@@ -423,6 +426,7 @@ namespace swift {
     int     Listen (Address addr);
     /** Run send/receive loop for the specified amount of time. */
     void    Loop (tint till);
+    bool    Listen3rdPartySocket (sckrwecb_t);
     /** Stop listening to a port. */
     void    Shutdown (int sock_des=-1);
 
@@ -450,7 +454,12 @@ namespace swift {
     /** Returns the number of bytes that are complete sequentially, starting from the
         beginning, till the first not-yet-retrieved packet. */
     uint64_t  SeqComplete (int fdes);
+    /***/
+    int       Find (Sha1Hash hash);
 
+    void AddProgressCallback (int transfer,ProgressCallback cb,uint8_t agg);
+    void RemoveProgressCallback (int transfer,ProgressCallback cb);
+    void ExternallyRetrieved (int transfer,bin64_t piece);
 
     //uint32_t Width (const tbinvec& v);
 
@@ -461,5 +470,11 @@ namespace swift {
 
 } // namespace end
 
+#ifndef SWIFT_MUTE
+#define dprintf(...) { if (Channel::debug_file) fprintf(Channel::debug_file,__VA_ARGS__); }
+#else
+#define dprintf(...) {}
+#endif
+#define eprintf(...) fprintf(stderr,__VA_ARGS__)
 
 #endif