00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00066
00067 SetConnectionRetry(-1);
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
00089
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
00103
00104 delete[] m_slice;
00105 }
00106
00107
00108 void pSocket::OnAccept()
00109 {
00110 DEB(printf("pSocket::OnAccept()\n");)
00111
00112
00113
00114
00115
00116
00117
00118
00119
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;
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;
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
00180
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
00200
00201
00202 Session *sess = m_sess;
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;
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
00267 if (m_server)
00268 {
00269
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());
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
00302
00303
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
00314 SetCloseAndDelete();
00315 return;
00316 }
00317 }
00318 }
00319 else
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
00343
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
00355
00356
00357
00358
00359
00360
00361
00362
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
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
00528 if (m_ptr == m_length_cmd)
00529 {
00530 m_state = STATE_COMMAND;
00531 }
00532 }
00533 break;
00534 }
00535 }
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
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;
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;
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
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;
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
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;
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
00694 }
00695
00696
00697 Peer *pSocket::GetPeer()
00698 {
00699 return m_peer;
00700
00701
00702
00703
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;
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;
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;
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;
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