Logo
~Apps~
~Projects~
~Contact~


pSocket.cpp

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2005  Anders Hedstrom
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 */
00023 #ifdef _WIN32
00024 #pragma warning(disable:4786)
00025 typedef __int64 int64_t;
00026 typedef unsigned __int64 uint64_t;
00027 typedef unsigned __int32 uint32_t;
00028 #else
00029 #include <stdint.h>
00030 #endif
00031 
00032 #include "PeerHandler.h"
00033 #include "Session.h"
00034 #include "Peer.h"
00035 #include "Piece.h"
00036 #include "pSocket.h"
00037 
00038 #ifdef _DEBUG
00039 #define DEB(x) x
00040 #else
00041 #define DEB(x) x
00042 #endif
00043 
00044 
00045 
00046 int pSocket::m_next_id = 0;
00047 
00048 pSocket::pSocket(ISocketHandler& h)
00049 :TcpSocket(h)
00050 ,m_state(ACCEPT_LENGTH)
00051 ,m_server(false)
00052 ,m_cmd(0)
00053 ,m_slice(new unsigned char[SLICE])
00054 ,m_id(++m_next_id)
00055 ,m_interest(false)
00056 ,m_choke(true)
00057 ,m_t_choke(time(NULL))
00058 ,m_cts(false)
00059 ,m_sess(NULL)
00060 ,m_peer(NULL)
00061 ,m_last_r(0)
00062 ,m_last_w(0)
00063 ,m_last_r_ptr(0)
00064 {
00065 //DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)pSocket", m_id);)
00066 //DEB(printf("pSocket()\n");)
00067         SetConnectionRetry(-1); // retry forever
00068 }
00069 
00070 
00071 pSocket::pSocket(ISocketHandler& h,const std::string& hash,unsigned char *p)
00072 :TcpSocket(h)
00073 ,m_hash(hash)
00074 ,m_state(ACCEPT_LENGTH)
00075 ,m_server(false)
00076 ,m_cmd(0)
00077 ,m_slice(new unsigned char[SLICE])
00078 ,m_id(++m_next_id)
00079 ,m_interest(false)
00080 ,m_choke(true)
00081 ,m_t_choke(time(NULL))
00082 ,m_cts(false)
00083 ,m_sess(NULL)
00084 ,m_peer(NULL)
00085 ,m_last_r(0)
00086 ,m_last_w(0)
00087 {
00088 //DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)pSocket", m_id);)
00089 //DEB(printf("pSocket()\n");)
00090         m_sess = static_cast<PeerHandler&>(h).GetSession(hash);
00091         if (!m_sess)
00092         {
00093                 SetCloseAndDelete();
00094                 return;
00095         }
00096         memcpy(m_remote_peer_id, p, 20);
00097 }
00098 
00099 
00100 pSocket::~pSocket()
00101 {
00102 //DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)~pSocket", m_id);)
00103 //DEB(printf("~pSocket()\n");)
00104         delete[] m_slice;
00105 }
00106 
00107 
00108 void pSocket::OnAccept()
00109 {
00110 DEB(printf("pSocket::OnAccept()\n");)
00111 //DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnAccept", m_id);)
00112         // 0x13
00113         // 'BitTorrent protocol'
00114         // 8 x 0x00
00115         // 20 byte hash
00116         // 20 byte peer id
00117         //  (If the receiving side's peer id doesn't match 
00118         //   the one the initiating side expects, it severs
00119         //   the connection.)
00120         m_state = ACCEPT_LENGTH;
00121         m_server = true;
00122 }
00123 
00124 
00125 void pSocket::OnConnect()
00126 {
00127 DEB(printf("pSocket::OnConnect()\n");)
00128         m_peer = m_sess -> GetPeer(GetRemoteAddress());
00129         if (m_peer)
00130         {
00131                 m_peer -> SetChoked(true);
00132                 m_peer -> SetInterested(false);
00133         }
00134 DEB(    if (m_sess && (static_cast<PeerHandler&>(Handler()).GetDebug() & 1024))
00135                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnConnect", m_id);)
00136         SendHello();
00137         SendBitmap();
00138         m_state = ACCEPT_LENGTH;
00139 }
00140 
00141 
00142 void pSocket::OnDelete()
00143 {
00144 DEB(    if (m_sess && (static_cast<PeerHandler&>(Handler()).GetDebug() & 1024))
00145                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnDelete", m_id);)
00146 }
00147 
00148 
00149 void pSocket::SendHello()
00150 {
00151 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)SendHello", m_id);)
00152         Session *sess = m_sess; //ref.GetSession(m_hash);
00153         if (!sess)
00154         {
00155 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)SendHello: no session (fatal)", m_id);)
00156                 SetCloseAndDelete();
00157                 return;
00158         }
00159         char buf[68];
00160         *buf = 0x13;
00161         memcpy(buf + 1, "BitTorrent protocol", 19);
00162         memset(buf + 20, 0, 8);
00163         memcpy(buf + 28, sess -> GetHashptr(), 20);
00164         memcpy(buf + 48, sess -> GetPeerId(), 20);
00165         SendBuf(buf, 68);
00166 }
00167 
00168 
00169 void pSocket::SendBitmap()
00170 {
00171         Session *sess = m_sess; //ref.GetSession(m_hash);
00172         if (!sess)
00173         {
00174 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)SendBitmap: no session (fatal)", m_id);)
00175                 SetCloseAndDelete();
00176                 return;
00177         }
00178         piece_v& pcs = sess -> Complete();
00179         // TODO: uncomment..
00180 //      if (pcs.size())
00181         {
00182                 bitmap_t bitmap(sess -> GetNumberOfPieces());
00183                 for (piece_v::iterator it = pcs.begin(); it != pcs.end(); it++)
00184                 {
00185                         Piece *p = *it;
00186                         bitmap.set(p -> GetNumber());
00187                 }
00188                 uint32_t l = htonl(bitmap.GetBitmapSize() + 1);
00189                 SendBuf( (char *)&l, 4);
00190                 Send("\05");
00191                 SendBuf( (char *)bitmap.GetBitmap(),bitmap.GetBitmapSize());
00192         }
00193 }
00194 
00195 
00196 void pSocket::OnRead()
00197 {
00198 /*
00199 if (m_state != STATE_GET_PIECE)
00200         DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead, state = %d, ptr = %d", m_id, m_state, m_ptr);)
00201 */
00202         Session *sess = m_sess; //ref.GetSession(m_hash);
00203         if (!sess && m_hash.size() )
00204         {
00205 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead: no session (fatal)", m_id);)
00206                 SetCloseAndDelete();
00207                 return;
00208         }
00209         Peer *peer = m_peer; //sess ? sess -> GetPeer(GetRemoteAddress()) : NULL;
00210         char slask[100];
00211         TcpSocket::OnRead();
00212         while (ibuf.GetLength() && !CloseAndDelete() )
00213         {
00214                 size_t l = ibuf.GetLength();
00215 DEB(printf("OnRead: %d bytes, state %d\n", l, m_state);)
00216                 switch (m_state)
00217                 {
00218                 case ACCEPT_LENGTH:
00219                         {
00220                                 char c;
00221                                 ibuf.Read(&c, 1);
00222                                 if (c != 0x13)
00223                                 {
00224 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead: protocol length != 0x13 (fatal)", m_id);)
00225                                         SetCloseAndDelete();
00226                                         return;
00227                                 }
00228                                 m_state = ACCEPT_PROTOCOL;
00229                         }
00230                         break;
00231                 case ACCEPT_PROTOCOL:
00232                         if (l < 19)
00233                         {
00234                                 return;
00235                         }
00236                         ibuf.Read(slask, 19);
00237                         slask[19] = 0;
00238                         if (strcmp(slask, "BitTorrent protocol"))
00239                         {
00240 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead: protocol != BitTorrent protocol (fatal)", m_id);)
00241                                 SetCloseAndDelete();
00242                                 return;
00243                         }
00244                         m_state = ACCEPT_NULLBYTES;
00245                         break;
00246                 case ACCEPT_NULLBYTES:
00247                         if (l < 8)
00248                                 return;
00249                         ibuf.Read(slask, 8);
00250                         m_state = ACCEPT_HASH;
00251                         break;
00252                 case ACCEPT_HASH:
00253                         if (l < 20)
00254                                 return;
00255                         ibuf.Read(slask, 20);
00256                         {
00257                                 std::string hash;
00258                                 for (size_t i = 0; i < 20; i++)
00259                                 {
00260                                         unsigned char c;
00261                                         char tmp[10];
00262                                         memcpy(&c, slask + i, 1);
00263                                         sprintf(tmp, "%02x", c);
00264                                         hash += tmp;
00265                                 }
00266 //DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead: %s", m_id, hash.c_str() );)
00267                                 if (m_server) // incoming
00268                                 {
00269                                         // resolve session for incoming connection (m_sess is NULL)
00270                                         Session *s = static_cast<PeerHandler&>(Handler()).GetSession(hash);
00271                                         if (!s)
00272                                         {
00273 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead: bad incoming hash (fatal)", m_id);)
00274                                                 SetCloseAndDelete();
00275                                                 return;
00276                                         }
00277                                         m_hash = hash;
00278                                         m_sess = s;
00279                                         m_peer = s -> GetPeer(GetRemoteAddress()); // can be NULL
00280                                         sess = s;
00281                                         peer = m_peer;
00282                                 }
00283                                 if (hash != m_hash)
00284                                 {
00285 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead: unexpected hash (fatal)", m_id);)
00286                                         SetCloseAndDelete();
00287                                         return;
00288                                 }
00289                                 if (m_server)
00290                                 {
00291                                         SendHello();
00292                                         SendBitmap();
00293                                 }
00294                                 m_state = ACCEPT_PEER_ID;
00295                         }
00296                         break;
00297                 case ACCEPT_PEER_ID:
00298                         if (l < 20)
00299                                 return;
00300                         ibuf.Read(slask, 20);
00301                         //  (If the receiving side's peer id doesn't match 
00302                         //   the one the initiating side expects, it severs
00303                         //   the connection.)
00304                         if (!m_server)
00305                         {
00306                                 bool ok = true;
00307                                 for (size_t i = 0; i < 20 && ok; i++)
00308                                         if (m_remote_peer_id[i] != (unsigned char)(slask[i]) )
00309                                                 ok = false;
00310                                 if (!ok)
00311                                 {
00312                                         {
00313 //DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead: peer id (fatal)", m_id);)
00314                                                 SetCloseAndDelete();
00315                                                 return;
00316                                         }
00317                                 }
00318                         }
00319                         else // if (m_server)
00320                         {
00321                                 std::string ip = GetRemoteAddress();
00322                                 std::string id = static_cast<std::string>(slask).substr(0,20);
00323                                 if (sess && !sess -> GetPeer(ip))
00324                                 {
00325                                         Peer *p = new Peer(Handler(),m_hash,ip,id,0);
00326                                         sess -> AddPeer(p);
00327                                         m_peer = p;
00328                                         peer = p;
00329                                 }
00330                         }
00331                         m_state = STATE_COMMAND;
00332                         m_cts = true;
00333                         break;
00334                 case STATE_COMMAND:
00335                         if (l < 4)
00336                                 return;
00337                         {
00338                                 uint32_t len;
00339                                 ibuf.Read( (char *)&len, 4);
00340                                 m_length_cmd = ntohl(len);
00341 /*
00342 DEB(                            size_t msglen = ntohl(len);
00343 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead: next message length: %d", m_id, msglen);)
00344 */
00345                                 if (len > 0)
00346                                 {
00347                                         m_state = STATE_COMMAND2;
00348                                 }
00349                         }
00350                         break;
00351                 case STATE_COMMAND2:
00352                         ibuf.Read(&m_cmd, 1);
00353 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)Command: %d", m_id, m_cmd);
00354                         //     * 0 - choke
00355                         //     * 1 - unchoke
00356                         //     * 2 - interested
00357                         //     * 3 - not interested
00358                         //     * 4 - have [piece(integer)]
00359                         //     * 5 - bitfield [bitmap]
00360                         //     * 6 - request [index begin length]
00361                         //     * 7 - piece [index begin piece(byte[])]
00362                         //     * 8 - cancel [index begin length]
00363                         switch (m_cmd)
00364                         {
00365                         case 0:
00366                                 cmdChoke();
00367                                 m_state = STATE_COMMAND;
00368                                 break;
00369                         case 1:
00370                                 cmdUnchoke();
00371                                 m_state = STATE_COMMAND;
00372                                 break;
00373                         case 2:
00374                                 cmdInterested();
00375                                 m_state = STATE_COMMAND;
00376                                 break;
00377                         case 3:
00378                                 cmdNotinterested();
00379                                 m_state = STATE_COMMAND;
00380                                 break;
00381                         case 4:
00382                                 m_integers = 1;
00383                                 m_ptr = 0;
00384                                 m_state = STATE_GET_INTEGERS;
00385                                 break;
00386                         case 5:
00387                                 m_ptr = 0;
00388                                 m_state = STATE_GET_BITMAP;
00389                                 break;
00390                         case 6:
00391                                 m_integers = 3;
00392                                 m_ptr = 0;
00393                                 m_state = STATE_GET_INTEGERS;
00394                                 break;
00395                         case 7:
00396                                 m_integers = 2;
00397                                 m_ptr = 0;
00398                                 m_state = STATE_GET_INTEGERS;
00399                                 break;
00400                         case 8:
00401                                 m_integers = 3;
00402                                 m_ptr = 0;
00403                                 m_state = STATE_GET_INTEGERS;
00404                                 break;
00405                         default:
00406 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead: unknown command code %02x length %d bytes", m_id, m_cmd, m_length_cmd );
00407                                 m_ptr = 1;
00408                                 m_state = STATE_GET_COMMAND;
00409                         }
00410                         break;
00411                 case STATE_GET_INTEGERS:
00412                         if (l < 4)
00413                                 return;
00414                         uint32_t ll;
00415                         ibuf.Read( (char *)&ll, 4);
00416                         m_int[m_ptr++] = ntohl(ll);
00417                         if (m_ptr >= m_integers)
00418                         {
00419                                 switch (m_cmd)
00420                                 {
00421                                 case 4:
00422                                         if (m_int[0] < sess -> GetNumberOfPieces())
00423                                         {
00424                                                 cmdHave(m_int[0]);
00425                                                 m_state = STATE_COMMAND;
00426                                         }
00427                                         else
00428                                         {
00429 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead/STATE_GET_INTEGERS:4(Have)", m_id);)
00430                                                 SetCloseAndDelete();
00431                                         }
00432                                         break;
00433                                 case 6:
00434                                         if (m_int[0] < sess -> GetNumberOfPieces() &&
00435                                                 m_int[1] < sess -> GetPieceLength() &&
00436                                                 m_int[2] < 131072 &&
00437                                                 m_int[1] + m_int[2] <= sess -> GetPieceLength() &&
00438                                                 m_int[2] > 0)
00439                                         {
00440                                                 cmdRequest(m_int[0], m_int[1], m_int[2]);
00441                                                 m_state = STATE_COMMAND;
00442                                         }
00443                                         else
00444                                         {
00445 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead/STATE_GET_INTEGERS:6(Request)", m_id);)
00446                                                 SetCloseAndDelete();
00447                                         }
00448                                         break;
00449                                 case 7:
00450                                         m_ptr = 0;
00451                                         m_state = STATE_GET_PIECE;
00452                                         break;
00453                                 case 8:
00454                                         if (m_int[0] < sess -> GetNumberOfPieces() &&
00455                                                 m_int[1] < sess -> GetPieceLength() &&
00456                                                 m_int[2] < 131072 &&
00457                                                 m_int[1] + m_int[2] <= sess -> GetPieceLength() &&
00458                                                 m_int[2] > 0)
00459                                         {
00460                                                 cmdCancel(m_int[0], m_int[1], m_int[2]);
00461                                                 m_state = STATE_COMMAND;
00462                                         }
00463                                         else
00464                                         {
00465 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead/STATE_GET_INTEGERS:8(Cancel)", m_id);)
00466                                                 SetCloseAndDelete();
00467                                         }
00468                                         break;
00469                                 }
00470                         }
00471                         break;
00472                 case STATE_GET_BITMAP:
00473 //static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)waiting for bitmap size %d bytes", m_id, peer -> GetBitmapSize());
00474                         if (l < peer -> GetBitmapSize())
00475                                 return;
00476                         ibuf.Read( (char *)peer -> GetBitmap(), peer -> GetBitmapSize());
00477                         cmdBitfield();
00478                         m_state = STATE_COMMAND;
00479                         break;
00480                 case STATE_GET_PIECE:
00481                         if (m_ptr + l < SLICE)
00482                         {
00483                                 ibuf.Read( (char *)&m_slice[m_ptr], l);
00484                                 m_ptr += l;
00485                         }
00486                         else
00487                         {
00488                                 size_t sz = SLICE - m_ptr;
00489                                 ibuf.Read( (char *)&m_slice[m_ptr], sz);
00490                                 m_ptr += sz;
00491                         }
00492                         if (m_ptr >= SLICE)
00493                         {
00494                                 if (m_int[0] < sess -> GetNumberOfPieces() &&
00495                                         m_int[1] < sess -> GetPieceLength())
00496                                 {
00497                                         cmdPiece(m_int[0], m_int[1], m_slice);
00498                                         if (peer)
00499                                         {
00500                                                 peer -> RefreshRequests();
00501                                         }
00502                                         m_state = STATE_COMMAND;
00503                                 }
00504                                 else
00505                                 {
00506 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)OnRead/STATE_GET_PIECE", m_id);)
00507                                         SetCloseAndDelete();
00508                                 }
00509                         }
00510                         break;
00511                 case STATE_GET_COMMAND:
00512                         {
00513                                 std::string hex;
00514                                 std::string txt;
00515                                 char slask[10];
00516                                 while (m_ptr < m_length_cmd && l)
00517                                 {
00518                                         unsigned char c;
00519                                         ibuf.Read( (char *)&c,1);
00520                                         sprintf(slask,"%02x",c);
00521                                         hex += slask;
00522                                         sprintf(slask,"%c",isprint((char)c) ? (char)c : '.');
00523                                         txt += slask;
00524                                         l--;
00525                                         m_ptr++;
00526                                 }
00527 //DEB(printf("%s\n%s\n",hex.c_str(),txt.c_str());)
00528                                 if (m_ptr == m_length_cmd)
00529                                 {
00530                                         m_state = STATE_COMMAND;
00531                                 }
00532                         }
00533                         break;
00534                 }
00535         }
00536 }
00537 
00538 
00539                         //     * 0 - choke 1
00540                         //     * 1 - unchoke 2
00541                         //     * 2 - interested 4
00542                         //     * 3 - not interested 8
00543                         //     * 4 - have [piece(integer)] 16
00544                         //     * 5 - bitfield [bitmap] 32
00545                         //     * 6 - request [index begin length] 64
00546                         //     * 7 - piece [index begin piece(byte[])] 128
00547                         //     * 8 - cancel [index begin length] 256
00548 void pSocket::cmdChoke()
00549 {
00550         Peer *peer = GetPeer();
00551 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00552         if (debug & 1)
00553                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, ">(%d)Choke", m_id);)
00554         if (peer)
00555         {
00556                 peer -> SetChoked(true);
00557                 peer -> RemoveRequests();
00558         }
00559 }
00560 
00561 
00562 void pSocket::cmdUnchoke()
00563 {
00564         Peer *peer = GetPeer();
00565 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00566         if (debug & 2)
00567                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, ">(%d)Unchoke", m_id);)
00568         if (peer)
00569         {
00570                 peer -> SetChoked(false);
00571                 peer -> RequestAvailable();
00572         }
00573 }
00574 
00575 
00576 void pSocket::cmdInterested()
00577 {
00578 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00579         if (debug & 4)
00580                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, ">(%d)Interested", m_id);)
00581         Peer *peer = GetPeer();
00582         if (peer)
00583                 peer -> SetInterested(true);
00584 }
00585 
00586 
00587 void pSocket::cmdNotinterested()
00588 {
00589 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00590         if (debug & 8)
00591                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, ">(%d)Notinterested", m_id);)
00592         Peer *peer = GetPeer();
00593         if (peer)
00594                 peer -> SetInterested(false);
00595         if (!m_choke)
00596                 SendChoke(true);
00597 }
00598 
00599 
00600 void pSocket::cmdHave(size_t piece)
00601 {
00602 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00603         if (debug & 16)
00604                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, ">(%d)Have(%d)", m_id, piece);)
00605         Session *sess = m_sess; //ref.GetSession(m_hash);
00606         if (!sess)
00607         {
00608 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)cmdRequest: no session (fatal)", m_id);)
00609                 SetCloseAndDelete();
00610                 return;
00611         }
00612         Peer *peer = GetPeer();
00613         if (peer)
00614         {
00615                 peer -> set(piece);
00616         }
00617         sess -> SetUpdateInterested();
00618 }
00619 
00620 
00621 void pSocket::cmdBitfield()
00622 {
00623 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00624         if (debug & 32)
00625                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, ">(%d)Bitfield", m_id);)
00626         Session *sess = m_sess; //ref.GetSession(m_hash);
00627         if (!sess)
00628         {
00629 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)cmdRequest: no session (fatal)", m_id);)
00630                 SetCloseAndDelete();
00631                 return;
00632         }
00633         sess -> SetUpdateInterested();
00634 //      SendChoke(false);
00635 }
00636 
00637 
00638 void pSocket::cmdRequest(size_t piece, size_t offset, size_t length)
00639 {
00640 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00641         if (debug & 64)
00642                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, ">(%d)Request(%d,%d,%d)", m_id, piece, offset, length);)
00643         Session *sess = m_sess; //ref.GetSession(m_hash);
00644         if (!sess)
00645         {
00646 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)cmdRequest: no session (fatal)", m_id);)
00647                 SetCloseAndDelete();
00648                 return;
00649         }
00650         // TODO
00651         if (0&&sess -> SliceSent(piece, offset))
00652         {
00653                 SendChoke(true);
00654         }
00655         else
00656         {
00657                 SendPiece(piece, offset, length);
00658         }
00659 }
00660 
00661 
00662 void pSocket::cmdCancel(size_t piece, size_t offset, size_t length)
00663 {
00664 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00665         if (debug & 256)
00666                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, ">(%d)Cancel(%d,%d,%d)", m_id, piece, offset, length);)
00667 }
00668 
00669 
00670 void pSocket::cmdPiece(size_t piece, size_t offset, unsigned char *data)
00671 {
00672 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00673         if (debug & 128)
00674                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, ">(%d)Piece(%d,%d)", m_id, piece, offset);)
00675         Session *sess = m_sess; //ref.GetSession(m_hash);
00676         if (!sess)
00677         {
00678 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)cmdPiece: no session (fatal)", m_id);)
00679                 SetCloseAndDelete();
00680                 return;
00681         }
00682         Peer *peer = GetPeer();
00683         size_t length = peer ? peer -> GotSlice(piece, offset) : 0;
00684         if (length)
00685         {
00686                 sess -> SaveSlice(piece, offset, length, data);
00687                 sess -> SetCheckComplete();
00688         }
00689         else
00690         {
00691 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)cmdPiece: no length for slice write", m_id);)
00692         }
00693 //      sess -> GenerateRequest(peer);
00694 }
00695 
00696 
00697 Peer *pSocket::GetPeer()
00698 {
00699         return m_peer;
00700 /*
00701         PeerHandler& ref = static_cast<PeerHandler&>(Handler());
00702         Session *sess = ref.GetSession(m_hash);
00703         return sess ? sess -> GetPeer(GetRemoteAddress()) : NULL;
00704 */
00705 }
00706 
00707 
00708 void pSocket::SendInterest(bool interested)
00709 {
00710 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00711         if ((interested && (debug&4)) || (!interested && (debug&8)))
00712                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "<(%d)SendInterest(%s)", m_id, interested ? "true" : "false" );)
00713         uint32_t l = htonl(1);
00714         SendBuf( (char *)&l, 4);
00715         if (interested)
00716                 Send("\02");
00717         else
00718                 Send("\03");
00719         m_interest = interested;
00720 }
00721 
00722 
00723 void pSocket::SendRequest(size_t piece,size_t offset,size_t length)
00724 {
00725 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00726         if (debug & 64)
00727                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "<(%d)SendRequest(%d,%d,%d)", m_id, piece, offset, length );)
00728         uint32_t tmp = htonl(piece);
00729         char buf[13];
00730         *buf = 6; // request
00731         memcpy(buf + 1, &tmp, 4);
00732         tmp = htonl(offset);
00733         memcpy(buf + 5, &tmp, 4);
00734         tmp = htonl(length);
00735         memcpy(buf + 9, &tmp, 4);
00736         uint32_t l = htonl(13);
00737         SendBuf( (char *)&l, 4);
00738         SendBuf(buf, 13);
00739 }
00740 
00741 
00742 void pSocket::SendCancel(size_t piece,size_t offset,size_t length)
00743 {
00744 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00745         if (debug & 256)
00746                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "<(%d)SendCancel(%d,%d,%d)", m_id, piece, offset, length );)
00747         uint32_t tmp = htonl(piece);
00748         char buf[13];
00749         *buf = 8; // cancel
00750         memcpy(buf + 1, &tmp, 4);
00751         tmp = htonl(offset);
00752         memcpy(buf + 5, &tmp, 4);
00753         tmp = htonl(length);
00754         memcpy(buf + 9, &tmp, 4);
00755         uint32_t l = htonl(13);
00756         SendBuf( (char *)&l, 4);
00757         SendBuf(buf, 13);
00758 }
00759 
00760 
00761 void pSocket::SendChoke(bool choke)
00762 {
00763 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00764         if ((choke && (debug&1)) || (!choke && (debug&2)))
00765                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "<(%d)SendChoke(%s)", m_id, choke ? "true" : "false" );)
00766         uint32_t l = htonl(1);
00767         SendBuf( (char *)&l, 4);
00768         if (choke)
00769                 Send("\00");
00770         else
00771                 Send("\01");
00772         m_choke = choke;
00773         if (choke)
00774                 m_t_choke = time(NULL);
00775 }
00776 
00777 
00778 void pSocket::SendHave(size_t piece)
00779 {
00780 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00781         if (debug & 16)
00782                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "<(%d)SendHave(%d)", m_id, piece );)
00783         uint32_t l = htonl(piece);
00784         uint32_t sz = htonl(5);
00785         SendBuf( (char *)&sz, 4);
00786         Send("\04");
00787         SendBuf( (char *)&l, 4);
00788 }
00789 
00790 
00791 void pSocket::SendPiece(size_t piece,size_t offset,size_t length)
00792 {
00793 DEB(    int debug = static_cast<PeerHandler&>(Handler()).GetDebug();
00794         if (debug & 128)
00795                 static_cast<PeerHandler&>(Handler()).dprintf(m_id, "<(%d)SendPiece(%d,%d,%d)", m_id, piece, offset, length );)
00796         Session *sess = m_sess; //ref.GetSession(m_hash);
00797         if (!sess)
00798         {
00799 DEB(static_cast<PeerHandler&>(Handler()).dprintf(m_id, "(%d)SendPiece: no session (fatal)", m_id);)
00800                 SetCloseAndDelete();
00801                 return;
00802         }
00803         sess -> SendSlice(this, piece, offset, length);
00804 }
00805 
00806 
00807 void pSocket::OnConnectFailed()
00808 {
00809         Peer *peer = GetPeer();
00810         if (peer)
00811                 peer -> SetFailed();
00812 }
00813 
00814 
00815 size_t pSocket::GetBytesR()
00816 {
00817         size_t sz = GetBytesReceived() - m_last_r;
00818         m_last_r = GetBytesReceived();
00819         m_last_r_buf[m_last_r_ptr++ % DLCHECKSIZE] = m_last_r;
00820         return sz;
00821 }
00822 
00823 
00824 size_t pSocket::GetBytesW()
00825 {
00826         size_t sz = GetBytesSent() - m_last_w;
00827         m_last_w = GetBytesSent();
00828         return sz;
00829 }
00830 
00831 
00832 bool pSocket::GetDownloadRate(size_t& sz)
00833 {
00834         if (m_last_r_ptr >= DLCHECKSIZE)
00835         {
00836                 int ptr = m_last_r_ptr - 1;
00837                 sz = m_last_r_buf[ptr % DLCHECKSIZE] - m_last_r_buf[m_last_r_ptr % 60];
00838                 sz /= DLCHECKSIZE; // bytes / sec
00839                 return true;
00840         }
00841         return false;
00842 }
00843 
00844 
00845 void pSocket::ShowStatus(size_t max)
00846 {
00847         if (CTS())
00848         {
00849                 std::string client = "unknown";
00850                 std::string version = "-";
00851                 std::string id = GetPeer() -> GetID();
00852                 switch (id[0])
00853                 {
00854                 case '-':
00855                         if (id.substr(1,2) == "AZ")
00856                                 client = "Azureus";
00857                         if (id.substr(1,2) == "BB")
00858                                 client = "BitBuddy";
00859                         if (id.substr(1,2) == "CT")
00860                                 client = "CTorrent";
00861                         if (id.substr(1,2) == "MT")
00862                                 client = "MoonlightTorrent";
00863                         if (id.substr(1,2) == "LT")
00864                                 client = "libtorrent";
00865                         if (id.substr(1,2) == "BX")
00866                                 client = "Bittorrent X";
00867                         if (id.substr(1,2) == "TS")
00868                                 client = "Torrentstorm";
00869                         if (id.substr(1,2) == "TN")
00870                                 client = "TorrentDotNET";
00871                         if (id.substr(1,2) == "SS")
00872                                 client = "SwarmScope";
00873                         if (id.substr(1,2) == "XT")
00874                                 client = "XanTorrent";
00875                         if (id.substr(1,2) == "BS")
00876                                 client = "BTSlave";
00877                         if (id.substr(1,2) == "ZT")
00878                                 client = "ZipTorrent";
00879                         if (id.substr(1,2) == "AR")
00880                                 client = "Arctic";
00881                         if (id.substr(1,2) == "SB")
00882                                 client = "Swiftbit";
00883                         if (id.substr(1,2) == "++")
00884                                 client = "C++";
00885                         version = id.substr(3,4);
00886                         break;
00887                 case 'S':
00888                         client = "Shadow";
00889                         version = id.substr(1,3);
00890                         break;
00891                 case 'U':
00892                         client = "UPnP NAT Bit Torrent";
00893                         version = id.substr(1,3);
00894                         break;
00895                 case 'T':
00896                         client = "BitTornado";
00897                         version = id.substr(1,3);
00898                         break;
00899                 case 'A':
00900                         client = "ABC";
00901                         version = id.substr(1,3);
00902                         break;
00903                 case 'M':
00904                         client = "Brams";
00905                         version = id.substr(1,7);
00906                         break;
00907                 case 'e':
00908                         client = "BitComet";
00909                         break;
00910                 }
00911                 char up[100];
00912                 char dn[100];
00913                 if (GetBytesSent() / 1024 > 999)
00914                         sprintf(up, "%4d MB", GetBytesSent() / (1024 * 1024));
00915                 else
00916                         sprintf(up, "%4d kB", GetBytesSent() / 1024);
00917                 if (GetBytesReceived() / 1024 > 999)
00918                         sprintf(dn, "%4d MB", GetBytesReceived() / (1024 * 1024));
00919                 else
00920                         sprintf(dn, "%4d kB", GetBytesReceived() / 1024);
00921                 {
00922                         std::string tmp;
00923                         for (size_t i = 0; i < version.size(); i++)
00924                                 tmp += isprint(version[i]) ? version[i] : '.';
00925                         version = tmp;
00926                 }
00927                 static_cast<PeerHandler&>(Handler()).dprintf(m_id,
00928                         "(%5d)%18s  %5d / %d  (%16s/%7s)  UL:%s  DL:%s", 
00929                         m_id, GetRemoteAddress().c_str(),
00930                         GetPeer() -> GetSet(), max, client.c_str(), version.c_str(),
00931                         up, dn);
00932         }
00933 }
00934 
00935 
Page, code, and content Copyright (C) 2006 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4