Better incapsulation
authorVictor Grishchenko <victor.grishchenko@gmail.com>
Mon, 25 Jan 2010 13:02:38 +0000 (14:02 +0100)
committerVictor Grishchenko <victor.grishchenko@gmail.com>
Mon, 25 Jan 2010 13:02:38 +0000 (14:02 +0100)
Channel now is a class.

p2tp.cpp
p2tp.h
send_control.cpp
sendrecv.cpp
transfer.cpp

index ee42009..65390d9 100644 (file)
--- a/p2tp.cpp
+++ b/p2tp.cpp
@@ -53,20 +53,20 @@ Channel::Channel    (FileTransfer* transfer, int socket, Address peer_addr) :
 {
     if (peer_==Address())
         peer_ = tracker;
-    this->id = channels.size();
+    this->id_ = channels.size();
     channels.push_back(this);
-    transfer_->hs_in_.push_back(id);
+    transfer_->hs_in_.push_back(id_);
     for(int i=0; i<4; i++) {
         owd_min_bins_[i] = TINT_NEVER;
         owd_current_[i] = TINT_NEVER;
     }
     Reschedule();
-    dprintf("%s #%u init %s\n",tintstr(),id,peer_.str());
+    dprintf("%s #%u init %s\n",tintstr(),id_,peer_.str());
 }
 
 
 Channel::~Channel () {
-    channels[id] = NULL;
+    channels[id_] = NULL;
 }
 
 
diff --git a/p2tp.h b/p2tp.h
index 6812db5..e70d18f 100644 (file)
--- a/p2tp.h
+++ b/p2tp.h
@@ -221,8 +221,8 @@ namespace p2tp {
         lots of other TCP stuff, sizeof(Channel+members) must be below 1K.
         (There was a seductive idea to remove channels, just put the root
         hash or a fragment of it into every datagram.) */
-    struct Channel {  // normally, API users do not deal with the structure
-
+    class Channel {  // normally, API users do not deal with the structure
+    public:
         Channel    (FileTransfer* file, int socket=-1, Address peer=Address());
         ~Channel();
         
@@ -287,20 +287,23 @@ namespace p2tp {
         tint ack_timeout () {
             return rtt_avg_ + std::max(dev_avg_,MIN_DEV)*4;
         }
+        uint32_t    id () const { return id_; }
         
-        static int DecodeID(int scrambled);
-        static int EncodeID(int unscrambled);
+        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. */
-        uint32_t    id;
+        uint32_t    id_;
         /**    Socket address of the peer. */
         Address     peer_;
         /**    The UDP socket fd. */
-        int         socket_;
+        SOCKET      socket_;
         /**    Descriptor of the file in question. */
         FileTransfer*    transfer_;
         /**    Peer channel id; zero if we are trying to open a channel. */
@@ -384,8 +387,6 @@ namespace p2tp {
         friend void     SetTracker(const Address& tracker);
         friend int      Open (const char*, const Sha1Hash&) ; // FIXME
 
-        friend class FileTransfer; // FIXME!!!
-        friend class SendController; // FIXME!!!
     };
 
 
index a7d4167..4e504dd 100644 (file)
@@ -33,7 +33,7 @@ tint    Channel::NextSendTime () {
 }
 
 tint    Channel::SwitchSendControl (int control_mode) {
-    dprintf("%s #%u sendctrl switch %s->%s\n",tintstr(),id,
+    dprintf("%s #%u sendctrl switch %s->%s\n",tintstr(),id(),
             SEND_CONTROL_MODES[send_control_],SEND_CONTROL_MODES[control_mode]);
     switch (control_mode) {
         case KEEP_ALIVE_CONTROL:
@@ -97,7 +97,7 @@ tint    Channel::CwndRateNextSendTime () {
     if (send_interval_>std::max(rtt_avg_,TINT_SEC)*4)
         return SwitchSendControl(KEEP_ALIVE_CONTROL);
     if (data_out_.size()<cwnd_) {
-        dprintf("%s #%u sendctrl next in %llius\n",tintstr(),id,send_interval_);
+        dprintf("%s #%u sendctrl next in %llius\n",tintstr(),id_,send_interval_);
         return last_data_out_time_ + send_interval_;
     } else {
         assert(data_out_.front().time!=TINT_NEVER);
@@ -111,7 +111,7 @@ void    Channel::BackOffOnLosses (float ratio) {
     if (last_loss_time_<NOW-rtt_avg_) {
         cwnd_ *= ratio;
         last_loss_time_ = NOW;
-        dprintf("%s #%u sendctrl backoff %3.2f\n",tintstr(),id,cwnd_);
+        dprintf("%s #%u sendctrl backoff %3.2f\n",tintstr(),id_,cwnd_);
     }
 }
 
@@ -155,7 +155,7 @@ tint Channel::LedbatNextSendTime () {
     tint off_target = LEDBAT_TARGET - queueing_delay;
     cwnd_ += LEDBAT_GAIN * off_target / cwnd_;
     dprintf("%s #%u sendctrl ledbat %lli-%lli => %3.2f\n",
-            tintstr(),id,owd_cur,owd_min,cwnd_);
+            tintstr(),id_,owd_cur,owd_min,cwnd_);
     return CwndRateNextSendTime();
 }
 
index 02dc62b..c49841c 100644 (file)
@@ -26,7 +26,7 @@ void    Channel::AddPeakHashes (Datagram& dgram) {
         dgram.Push32((uint32_t)peak);
         dgram.PushHash(file().peak_hash(i));
         //DLOG(INFO)<<"#"<<id<<" +pHASH"<<file().peak(i);
-        dprintf("%s #%u +phash %s\n",tintstr(),id,peak.str());
+        dprintf("%s #%u +phash %s\n",tintstr(),id_,peak.str());
     }
 }
 
@@ -40,7 +40,7 @@ void    Channel::AddUncleHashes (Datagram& dgram, bin64_t pos) {
         dgram.Push32((uint32_t)uncle);
         dgram.PushHash( file().hash(uncle) );
         //DLOG(INFO)<<"#"<<id<<" +uHASH"<<uncle;
-        dprintf("%s #%u +hash %s\n",tintstr(),id,uncle.str());
+        dprintf("%s #%u +hash %s\n",tintstr(),id_,uncle.str());
         pos = pos.parent();
     }
 }
@@ -61,7 +61,7 @@ bin64_t        Channel::DequeueHint () {
         if (my_pick!=bin64_t::NONE) {
             my_pick = my_pick.twisted(twist);
             hint_in_.push_back(my_pick);
-            dprintf("%s #%u *hint %s\n",tintstr(),id,my_pick.str());
+            dprintf("%s #%u *hint %s\n",tintstr(),id_,my_pick.str());
         }
     }
     bin64_t send = bin64_t::NONE;
@@ -81,7 +81,7 @@ bin64_t        Channel::DequeueHint () {
     uint64_t mass = 0;
     for(int i=0; i<hint_in_.size(); i++)
         mass += hint_in_[i].bin.width();
-    dprintf("%s #%u dequeued %s [%lli]\n",tintstr(),id,send.str(),mass);
+    dprintf("%s #%u dequeued %s [%lli]\n",tintstr(),id_,send.str(),mass);
     return send;
 }
 
@@ -92,12 +92,12 @@ void    Channel::AddHandshake (Datagram& dgram) {
         dgram.Push32(bin64_t::ALL32);
         dgram.PushHash(file().root_hash());
         dprintf("%s #%u +hash ALL %s\n",
-                tintstr(),id,file().root_hash().hex().c_str());
+                tintstr(),id_,file().root_hash().hex().c_str());
     }
     dgram.Push8(P2TP_HANDSHAKE);
-    int encoded = EncodeID(id);
+    int encoded = EncodeID(id_);
     dgram.Push32(encoded);
-    dprintf("%s #%u +hs %x\n",tintstr(),id,encoded);
+    dprintf("%s #%u +hs %x\n",tintstr(),id_,encoded);
     ack_out_.clear();
     AddAck(dgram);
 }
@@ -120,11 +120,11 @@ void    Channel::Send () {
         AddAck(dgram);
     }
     dprintf("%s #%u sent %ib %s:%x\n",
-            tintstr(),id,dgram.size(),peer().str(),peer_channel_id_);
+            tintstr(),id_,dgram.size(),peer().str(),peer_channel_id_);
     if (dgram.size()==4) {// only the channel id; bare keep-alive
         data = bin64_t::ALL;
         //dprintf("%s #%u considering keepalive %i %f %s\n",
-        //        tintstr(),id,(int)data_out_.size(),cwnd_,SEND_CONTROL_MODES[send_control_]);
+        //        tintstr(),id_,(int)data_out_.size(),cwnd_,SEND_CONTROL_MODES[send_control_]);
         //if (data_out_.size()<cwnd_ && send_control_!=KEEP_ALIVE_CONTROL) {
             //if ( cwnd_ < 1 )
             //    SwitchSendControl(KEEP_ALIVE_CONTROL);
@@ -167,11 +167,11 @@ void    Channel::AddHint (Datagram& dgram) {
         if (hint!=bin64_t::NONE) {
             dgram.Push8(P2TP_HINT);
             dgram.Push32(hint);
-            dprintf("%s #%u +hint %s [%lli]\n",tintstr(),id,hint.str(),hint_out_size_);
+            dprintf("%s #%u +hint %s [%lli]\n",tintstr(),id_,hint.str(),hint_out_size_);
             hint_out_.push_back(hint);
             hint_out_size_ += hint.width();
         } else
-            dprintf("%s #%u Xhint\n",tintstr(),id);
+            dprintf("%s #%u Xhint\n",tintstr(),id_);
         
     }
 }
@@ -186,12 +186,12 @@ bin64_t        Channel::AddData (Datagram& dgram) {
     if (data_out_.size()<cwnd_ && last_data_out_time_<=NOW-send_interval_) {
         tosend = DequeueHint();
         if (tosend==bin64_t::NONE) {
-            dprintf("%s #%u no idea what to send #sendctrl\n",tintstr(),id);
+            dprintf("%s #%u no idea what to send #sendctrl\n",tintstr(),id_);
             if (send_control_!=KEEP_ALIVE_CONTROL)
                 SwitchSendControl(KEEP_ALIVE_CONTROL);
         }
     } else
-        dprintf("%s #%u no cwnd #sendctrl\n",tintstr(),id);
+        dprintf("%s #%u no cwnd #sendctrl\n",tintstr(),id_);
     
     if (tosend==bin64_t::NONE)// && (last_data_out_time_>NOW-TINT_SEC || data_out_.empty())) 
         return bin64_t::NONE; // once in a while, empty data is sent just to check rtt FIXED
@@ -222,7 +222,7 @@ bin64_t        Channel::AddData (Datagram& dgram) {
     
     last_data_out_time_ = NOW;
     data_out_.push_back(tosend);
-    dprintf("%s #%u +data %s\n",tintstr(),id,tosend.str());
+    dprintf("%s #%u +data %s\n",tintstr(),id_,tosend.str());
     
     return tosend;
 }
@@ -231,7 +231,7 @@ bin64_t        Channel::AddData (Datagram& dgram) {
 void    Channel::AddTs (Datagram& dgram) {
     dgram.Push8(P2TP_TS);
     dgram.Push64(data_in_.time);
-    dprintf("%s #%u +ts %s\n",tintstr(),id,tintstr(data_in_.time));
+    dprintf("%s #%u +ts %s\n",tintstr(),id_,tintstr(data_in_.time));
 }
 
 
@@ -248,7 +248,7 @@ void    Channel::AddAck (Datagram& dgram) {
         dgram.Push32(pos.to32());
         //dgram.Push64(data_in_.time);
         ack_out_.set(pos);
-        dprintf("%s #%u +ack %s %s\n",tintstr(),id,pos.str(),tintstr(data_in_.time));
+        dprintf("%s #%u +ack %s %s\n",tintstr(),id_,pos.str(),tintstr(data_in_.time));
         data_in_ = tintbin(TINT_NEVER,bin64_t::NONE);
         if (pos.layer()>2)
             data_in_dbl_ = pos;
@@ -261,20 +261,20 @@ void    Channel::AddAck (Datagram& dgram) {
         ack_out_.set(ack);
         dgram.Push8(P2TP_ACK);
         dgram.Push32(ack.to32());
-        dprintf("%s #%u +ack %s\n",tintstr(),id,ack.str());
+        dprintf("%s #%u +ack %s\n",tintstr(),id_,ack.str());
     }
 }
 
 
 void    Channel::Recv (Datagram& dgram) {
-    dprintf("%s #%u recvd %i\n",tintstr(),id,dgram.size()+4);
+    dprintf("%s #%u recvd %i\n",tintstr(),id_,dgram.size()+4);
     peer_send_time_ = 0; // has scope of 1 datagram
     dgrams_rcvd_++;
     if (last_send_time_ && rtt_avg_==TINT_SEC && dev_avg_==0) {
         rtt_avg_ = NOW - last_send_time_;
         dev_avg_ = rtt_avg_;
         dip_avg_ = rtt_avg_;
-        dprintf("%s #%u rtt init %lli\n",tintstr(),id,rtt_avg_);
+        dprintf("%s #%u rtt init %lli\n",tintstr(),id_,rtt_avg_);
     }
     bin64_t data = dgram.size() ? bin64_t::NONE : bin64_t::ALL;
     while (dgram.size()) {
@@ -288,7 +288,7 @@ void    Channel::Recv (Datagram& dgram) {
             case P2TP_HINT:      OnHint(dgram); break;
             case P2TP_PEX_ADD:   OnPex(dgram); break;
             default:
-                eprintf("%s #%u ?msg id unknown %i\n",tintstr(),id,(int)type);
+                eprintf("%s #%u ?msg id unknown %i\n",tintstr(),id_,(int)type);
                 return;
         }
     }
@@ -302,7 +302,7 @@ void    Channel::OnHash (Datagram& dgram) {
     Sha1Hash hash = dgram.PullHash();
     file().OfferHash(pos,hash);
     //DLOG(INFO)<<"#"<<id<<" .HASH"<<(int)pos;
-    dprintf("%s #%u -hash %s\n",tintstr(),id,pos.str());
+    dprintf("%s #%u -hash %s\n",tintstr(),id_,pos.str());
 }
 
 
@@ -332,7 +332,7 @@ bin64_t Channel::OnData (Datagram& dgram) {
     uint8_t *data;
     int length = dgram.Pull(&data,1024);
     bool ok = (pos==bin64_t::NONE) || file().OfferData(pos, (char*)data, length) ;
-    dprintf("%s #%u %cdata %s\n",tintstr(),id,ok?'-':'!',pos.str());
+    dprintf("%s #%u %cdata %s\n",tintstr(),id_,ok?'-':'!',pos.str());
     data_in_ = tintbin(NOW,bin64_t::NONE);
     if (!ok) 
         return bin64_t::NONE;
@@ -372,7 +372,7 @@ void    Channel::CleanDataOut (bin64_t ackd_pos) { // TODO: isn't it too long?
                     if (owd_min_bins_[owd_min_bin_]>owd)
                         owd_min_bins_[owd_min_bin_] = owd;
                 }
-                dprintf("%s #%u rtt %lli dev %lli\n",tintstr(),id,rtt_avg_,dev_avg_);
+                dprintf("%s #%u rtt %lli dev %lli\n",tintstr(),id_,rtt_avg_,dev_avg_);
                 bin64_t pos = data_out_[i].bin;
                 ack_rcvd_recent_++;
                 data_out_[i]=tintbin();
@@ -394,7 +394,7 @@ void    Channel::CleanDataOut (bin64_t ackd_pos) { // TODO: isn't it too long?
             }
             while (max_ack_off>MAX_REORDERING) {
                 ack_not_rcvd_recent_++;
-                dprintf("%s #%u Rdata %s\n",tintstr(),id,data_out_.front().bin.str());
+                dprintf("%s #%u Rdata %s\n",tintstr(),id_,data_out_.front().bin.str());
                 data_out_.pop_front();
                 max_ack_off--;
                 data_out_cap_ = bin64_t::ALL;
@@ -406,7 +406,7 @@ void    Channel::CleanDataOut (bin64_t ackd_pos) { // TODO: isn't it too long?
         if (data_out_.front().bin!=bin64_t::NONE && ack_in_.is_empty(data_out_.front().bin)) {
             ack_not_rcvd_recent_++;
             data_out_cap_ = bin64_t::ALL;
-            dprintf("%s #%u Tdata %s\n",tintstr(),id,data_out_.front().bin.str());
+            dprintf("%s #%u Tdata %s\n",tintstr(),id_,data_out_.front().bin.str());
         }
         data_out_.pop_front();
     }
@@ -424,7 +424,7 @@ void    Channel::OnAck (Datagram& dgram) {
         eprintf("invalid ack: %s\n",ackd_pos.str());
         return;
     }
-    dprintf("%s #%u -ack %s\n",tintstr(),id,ackd_pos.str());
+    dprintf("%s #%u -ack %s\n",tintstr(),id_,ackd_pos.str());
     ack_in_.set(ackd_pos);
     CleanDataOut(ackd_pos); // FIXME do AFTER all ACKs
 }
@@ -432,7 +432,7 @@ void    Channel::OnAck (Datagram& dgram) {
 
 void Channel::OnTs (Datagram& dgram) {
     peer_send_time_ = dgram.Pull64();
-    dprintf("%s #%u -ts %lli\n",tintstr(),id,peer_send_time_);
+    dprintf("%s #%u -ts %lli\n",tintstr(),id_,peer_send_time_);
 }
 
 
@@ -441,13 +441,13 @@ void    Channel::OnHint (Datagram& dgram) {
     hint_in_.push_back(hint);
     //ack_in_.set(hint,binmap_t::EMPTY);
     //RequeueSend(cc_->OnHintRecvd(hint));
-    dprintf("%s #%u -hint %s\n",tintstr(),id,hint.str());
+    dprintf("%s #%u -hint %s\n",tintstr(),id_,hint.str());
 }
 
 
 void Channel::OnHandshake (Datagram& dgram) {
     peer_channel_id_ = dgram.Pull32();
-    dprintf("%s #%u -hs %x\n",tintstr(),id,peer_channel_id_);
+    dprintf("%s #%u -hs %x\n",tintstr(),id_,peer_channel_id_);
     // self-connection check
     if (!SELF_CONN_OK) {
         uint32_t try_id = DecodeID(peer_channel_id_);
@@ -464,20 +464,20 @@ void Channel::OnPex (Datagram& dgram) {
     uint32_t ipv4 = dgram.Pull32();
     uint16_t port = dgram.Pull16();
     Address addr(ipv4,port);
-    dprintf("%s #%u -pex %s\n",tintstr(),id,addr.str());
+    dprintf("%s #%u -pex %s\n",tintstr(),id_,addr.str());
     transfer().OnPexIn(addr);
 }
 
 
 void    Channel::AddPex (Datagram& dgram) {
     int chid = transfer().RevealChannel(pex_out_);
-    if (chid==-1 || chid==id)
+    if (chid==-1 || chid==id_)
         return;
     Address a = channels[chid]->peer();
     dgram.Push8(P2TP_PEX_ADD);
     dgram.Push32(a.ipv4());
     dgram.Push16(a.port());
-    dprintf("%s #%u +pex %s\n",tintstr(),id,a.str());
+    dprintf("%s #%u +pex %s\n",tintstr(),id_,a.str());
 }
 
 
@@ -547,12 +547,12 @@ void    Channel::Loop (tint howlong) {
         if ( sender!=NULL && send_time<=NOW ) { // it's time
             
             if (sender->next_send_time_<NOW+TINT_MIN) {  // either send
-                dprintf("%s #%u sch_send %s\n",tintstr(),sender->id,
+                dprintf("%s #%u sch_send %s\n",tintstr(),sender->id(),
                         tintstr(send_time));
                 sender->Send();
                 sender->Reschedule();
             } else { // or close the channel
-                dprintf("%s #%u closed sendctrl\n",tintstr(),sender->id);
+                dprintf("%s #%u closed sendctrl\n",tintstr(),sender->id());
                 delete sender;
             }
             
@@ -567,7 +567,7 @@ void    Channel::Loop (tint howlong) {
                     receiver->Reschedule();
             }
             if (sender)  // get back to that later
-                send_queue.push(tintbin(send_time,sender->id));
+                send_queue.push(tintbin(send_time,sender->id()));
             
         }
         
@@ -580,8 +580,8 @@ void Channel::Reschedule () {
     next_send_time_ = NextSendTime();
     if (next_send_time_!=TINT_NEVER) {
         assert(next_send_time_<NOW+TINT_MIN);
-        send_queue.push(tintbin(next_send_time_,id));
+        send_queue.push(tintbin(next_send_time_,id_));
     } else
-        send_queue.push(tintbin(NOW+TINT_MIN,id));
-    dprintf("%s requeue #%u for %s\n",tintstr(),id,tintstr(next_send_time_));
+        send_queue.push(tintbin(NOW+TINT_MIN,id_));
+    dprintf("%s requeue #%u for %s\n",tintstr(),id_,tintstr(next_send_time_));
 }
index 43ff713..08205ee 100644 (file)
@@ -39,14 +39,17 @@ FileTransfer::FileTransfer (const char* filename, const Sha1Hash& _root_hash) :
 }
 
 
+void    Channel::CloseTransfer (FileTransfer* trans) {
+    for(int i=0; i<Channel::channels.size(); i++) 
+        if (Channel::channels[i] && Channel::channels[i]->transfer_==trans) 
+            delete Channel::channels[i];
+}
+
 
 FileTransfer::~FileTransfer ()
 {
-
+    Channel::CloseTransfer(this);
     files[fd()] = NULL;
-    for(int i=0; i<Channel::channels.size(); i++) 
-        if (Channel::channels[i] && Channel::channels[i]->transfer_==this) 
-            delete Channel::channels[i];
 }
 
 
@@ -60,12 +63,12 @@ FileTransfer* FileTransfer::Find (const Sha1Hash& root_hash) {
 
 void            FileTransfer::OnPexIn (const Address& addr) {
     for(int i=0; i<hs_in_.size(); i++) {
-        Channel* c = Channel::channels[hs_in_[i]];
-        if (c && c->transfer().fd()==this->fd() && c->peer_==addr)
+        Channel* c = Channel::channel(hs_in_[i]);
+        if (c && c->transfer().fd()==this->fd() && c->peer()==addr)
             return; // already connected
     }
     if (hs_in_.size()<20) {
-        new Channel(this,Channel::sockets[0],addr);
+        new Channel(this,Channel::default_socket(),addr);
     } else {
         pex_in_.push_back(addr);
         if (pex_in_.size()>1000)
@@ -79,11 +82,11 @@ int        FileTransfer::RevealChannel (int& pex_out_) { // FIXME brainfuck
     if (pex_out_<0)
         pex_out_ = 0;
     while (pex_out_<hs_in_.size()) {
-        Channel* c = Channel::channels[hs_in_[pex_out_]];
+        Channel* c = Channel::channel(hs_in_[pex_out_]);
         if (c && c->transfer().fd()==this->fd()) {
-            if (c->own_id_mentioned_) {
+            if (c->is_established()) {
                 pex_out_ += hs_in_offset_ + 1;
-                return c->id;
+                return c->id();
             } else
                 pex_out_++;
         } else {