5 * Created by Victor Grishchenko on 3/6/09.
6 * Copyright 2009 Delft University of Technology. All rights reserved.
13 #include <sys/select.h>
16 #include <arpa/inet.h>
22 //#include <glog/logging.h>
27 using namespace swift;
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 socket_callbacks_t Channel::sockets[SWFT_MAX_SOCK_OPEN] = {};
35 int Channel::socket_count = 0;
36 Address Channel::tracker;
37 tbheap Channel::send_queue;
38 FILE* Channel::debug_file = NULL;
39 #include "ext/simple_selector.cpp"
40 PeerSelector* Channel::peer_selector = new SimpleSelector();
42 Channel::Channel (FileTransfer* transfer, int socket, Address peer_addr) :
43 transfer_(transfer), peer_(peer_addr), peer_channel_id_(0), pex_out_(0),
44 socket_(socket==INVALID_SOCKET?sockets[0].sock:socket), // FIXME
45 data_out_cap_(bin64_t::ALL), last_data_out_time_(0), last_data_in_time_(0),
46 own_id_mentioned_(false), next_send_time_(0), last_send_time_(0),
47 last_recv_time_(0), rtt_avg_(TINT_SEC), dev_avg_(0), dip_avg_(TINT_SEC),
48 data_in_dbl_(bin64_t::NONE), hint_out_size_(0),
49 cwnd_(1), send_interval_(TINT_SEC), send_control_(PING_PONG_CONTROL),
50 sent_since_recv_(0), ack_rcvd_recent_(0), ack_not_rcvd_recent_(0),
51 last_loss_time_(0), owd_min_bin_(0), owd_min_bin_start_(NOW),
52 owd_cur_bin_(0), dgrams_sent_(0), dgrams_rcvd_(0),
53 data_in_(TINT_NEVER,bin64_t::NONE)
57 this->id_ = channels.size();
58 channels.push_back(this);
59 transfer_->hs_in_.push_back(id_);
60 for(int i=0; i<4; i++) {
61 owd_min_bins_[i] = TINT_NEVER;
62 owd_current_[i] = TINT_NEVER;
65 dprintf("%s #%u init %s\n",tintstr(),id_,peer_.str());
69 Channel::~Channel () {
74 void swift::SetTracker(const Address& tracker) {
75 Channel::tracker = tracker;
79 int Channel::DecodeID(int scrambled) {
80 return scrambled ^ (int)Datagram::start;
82 int Channel::EncodeID(int unscrambled) {
83 return unscrambled ^ (int)Datagram::start;
87 int swift::Listen (Address addr) {
88 int sock = Datagram::Bind(addr);
89 if (sock!=INVALID_SOCKET) {
90 socket_callbacks_t cb(sock);
91 cb.may_read = &Channel::RecvDatagram;
92 Channel::sockets[Channel::socket_count++] = cb;
98 void swift::Shutdown (int sock_des) {
99 for(int i=0; i<Channel::socket_count; i++)
100 if (sock_des==-1 || Channel::sockets[i].sock==sock_des) {
101 Datagram::Close(Channel::sockets[i].sock);
102 Channel::sockets[i] = Channel::sockets[--Channel::socket_count];
107 void swift::Loop (tint till) {
112 bool swift::Listen3rdPartySocket (socket_callbacks_t cb) {
114 while (i<Channel::socket_count && Channel::sockets[i].sock!=cb.sock) i++;
115 if (i==Channel::socket_count)
116 if (i==SWFT_MAX_SOCK_OPEN)
119 Channel::socket_count++;
120 Channel::sockets[i]=cb;
121 if (!cb.may_read && !cb.may_write && !cb.on_error)
122 Channel::sockets[i] = Channel::sockets[--Channel::socket_count];
127 int swift::Open (const char* filename, const Sha1Hash& hash) {
128 FileTransfer* ft = new FileTransfer(filename, hash);
129 if (ft && ft->file().file_descriptor()) {
131 /*if (FileTransfer::files.size()<fdes) // FIXME duplication
132 FileTransfer::files.resize(fdes);
133 FileTransfer::files[fdes] = ft;*/
135 // initiate tracker connections
136 if (Channel::tracker!=Address())
139 return ft->file().file_descriptor();
148 void swift::Close (int fd) {
149 if (fd<FileTransfer::files.size() && FileTransfer::files[fd])
150 delete FileTransfer::files[fd];
154 void swift::AddPeer (Address address, const Sha1Hash& root) {
155 Channel::peer_selector->AddPeer(address,root);
159 uint64_t swift::Size (int fdes) {
160 if (FileTransfer::files.size()>fdes && FileTransfer::files[fdes])
161 return FileTransfer::files[fdes]->file().size();
167 bool swift::IsComplete (int fdes) {
168 if (FileTransfer::files.size()>fdes && FileTransfer::files[fdes])
169 return FileTransfer::files[fdes]->file().is_complete();
175 uint64_t swift::Complete (int fdes) {
176 if (FileTransfer::files.size()>fdes && FileTransfer::files[fdes])
177 return FileTransfer::files[fdes]->file().complete();
183 uint64_t swift::SeqComplete (int fdes) {
184 if (FileTransfer::files.size()>fdes && FileTransfer::files[fdes])
185 return FileTransfer::files[fdes]->file().seq_complete();
191 const Sha1Hash& swift::RootMerkleHash (int file) {
192 FileTransfer* trans = FileTransfer::file(file);
194 return Sha1Hash::ZERO;
195 return trans->file().root_hash();
199 /** <h2> swift handshake </h2>
202 <li> to send a datagram, a channel must be created
203 (channels are cheap and easily recycled)
204 <li> a datagram must contain either the receiving
205 channel id (scrambled) or the root hash