add .gitignore
[swift-upb.git] / channel.cpp
1 /*
2  *  swift.cpp
3  *  serp++
4  *
5  *  Created by Victor Grishchenko on 3/6/09.
6  *  Copyright 2009 Delft University of Technology. All rights reserved.
7  *
8  */
9
10 #include <stdlib.h>
11 #include <fcntl.h>
12 #ifndef _WIN32
13 #include <sys/select.h>
14 #include <sys/time.h>
15 #include <sys/mman.h>
16 #include <arpa/inet.h>
17 #include <unistd.h>
18 #endif
19 #include <sys/stat.h>
20 #include <string.h>
21
22 //#include <glog/logging.h>
23 #include "swift.h"
24 #include "datagram.h"
25
26 using namespace std;
27 using namespace swift;
28
29 swift::tint Channel::last_tick = 0;
30 int Channel::MAX_REORDERING = 4;
31 bool Channel::SELF_CONN_OK = false;
32 swift::tint Channel::TIMEOUT = TINT_SEC*60;
33 std::vector<Channel*> Channel::channels(1);
34 Address Channel::tracker;
35 tbheap Channel::send_queue;
36 FILE* Channel::debug_file = NULL;
37 #include "ext/simple_selector.cpp"
38 PeerSelector* Channel::peer_selector = new SimpleSelector();
39
40 Channel::Channel    (FileTransfer* transfer, int socket, Address peer_addr) :
41     transfer_(transfer), peer_(peer_addr), peer_channel_id_(0), pex_out_(0),
42     socket_(socket==INVALID_SOCKET?Datagram::default_socket():socket), // FIXME
43     data_out_cap_(bin64_t::ALL), last_data_out_time_(0), last_data_in_time_(0),
44     own_id_mentioned_(false), next_send_time_(0), last_send_time_(0),
45     last_recv_time_(0), rtt_avg_(TINT_SEC), dev_avg_(0), dip_avg_(TINT_SEC),
46     data_in_dbl_(bin64_t::NONE), hint_out_size_(0),
47     cwnd_(1), send_interval_(TINT_SEC), send_control_(PING_PONG_CONTROL),
48     sent_since_recv_(0), ack_rcvd_recent_(0), ack_not_rcvd_recent_(0),
49     last_loss_time_(0), owd_min_bin_(0), owd_min_bin_start_(NOW), 
50     owd_cur_bin_(0), dgrams_sent_(0), dgrams_rcvd_(0), 
51     data_in_(TINT_NEVER,bin64_t::NONE)
52 {
53     if (peer_==Address())
54         peer_ = tracker;
55     this->id_ = channels.size();
56     channels.push_back(this);
57     transfer_->hs_in_.push_back(id_);
58     for(int i=0; i<4; i++) {
59         owd_min_bins_[i] = TINT_NEVER;
60         owd_current_[i] = TINT_NEVER;
61     }
62     Reschedule();
63     dprintf("%s #%u init %s\n",tintstr(),id_,peer_.str());
64 }
65
66
67 Channel::~Channel () {
68     channels[id_] = NULL;
69 }
70
71
72 void     swift::SetTracker(const Address& tracker) {
73     Channel::tracker = tracker;
74 }
75
76
77 int Channel::DecodeID(int scrambled) {
78     return scrambled ^ (int)Datagram::start;
79 }
80 int Channel::EncodeID(int unscrambled) {
81     return unscrambled ^ (int)Datagram::start;
82 }
83
84
85 int     swift::Listen (Address addr) {
86     sckrwecb_t cb;
87     cb.may_read = &Channel::RecvDatagram;
88     cb.sock = Datagram::Bind(addr,cb);
89     return cb.sock;
90 }
91
92
93 void    swift::Shutdown (int sock_des) {
94     Datagram::Shutdown();
95 }
96
97
98 void    swift::Loop (tint till) {
99     Channel::Loop(till);
100 }
101
102
103
104 int      swift::Open (const char* filename, const Sha1Hash& hash) {
105     FileTransfer* ft = new FileTransfer(filename, hash);
106     if (ft && ft->file().file_descriptor()) {
107
108         /*if (FileTransfer::files.size()<fdes)  // FIXME duplication
109             FileTransfer::files.resize(fdes);
110         FileTransfer::files[fdes] = ft;*/
111
112         // initiate tracker connections
113         if (Channel::tracker!=Address())
114             new Channel(ft);
115
116         return ft->file().file_descriptor();
117     } else {
118         if (ft)
119             delete ft;
120         return -1;
121     }
122 }
123
124
125 void    swift::Close (int fd) {
126     if (fd<FileTransfer::files.size() && FileTransfer::files[fd])
127         delete FileTransfer::files[fd];
128 }
129
130
131 void    swift::AddPeer (Address address, const Sha1Hash& root) {
132     Channel::peer_selector->AddPeer(address,root);
133 }
134
135
136 uint64_t  swift::Size (int fdes) {
137     if (FileTransfer::files.size()>fdes && FileTransfer::files[fdes])
138         return FileTransfer::files[fdes]->file().size();
139     else
140         return 0;
141 }
142
143
144 bool  swift::IsComplete (int fdes) {
145     if (FileTransfer::files.size()>fdes && FileTransfer::files[fdes])
146         return FileTransfer::files[fdes]->file().is_complete();
147     else
148         return 0;
149 }
150
151
152 uint64_t  swift::Complete (int fdes) {
153     if (FileTransfer::files.size()>fdes && FileTransfer::files[fdes])
154         return FileTransfer::files[fdes]->file().complete();
155     else
156         return 0;
157 }
158
159
160 uint64_t  swift::SeqComplete (int fdes) {
161     if (FileTransfer::files.size()>fdes && FileTransfer::files[fdes])
162         return FileTransfer::files[fdes]->file().seq_complete();
163     else
164         return 0;
165 }
166
167
168 const Sha1Hash& swift::RootMerkleHash (int file) {
169     FileTransfer* trans = FileTransfer::file(file);
170     if (!trans)
171         return Sha1Hash::ZERO;
172     return trans->file().root_hash();
173 }
174
175
176 /**    <h2> swift handshake </h2>
177  Basic rules:
178  <ul>
179  <li>    to send a datagram, a channel must be created
180  (channels are cheap and easily recycled)
181  <li>    a datagram must contain either the receiving
182  channel id (scrambled) or the root hash
183  </ul>
184  <b>Note:</b>
185  */