00001 // 00002 // Neighbour.h 00003 // 00004 // Copyright (c) Shareaza Development Team, 2002-2005. 00005 // This file is part of SHAREAZA (www.shareaza.com) 00006 // 00007 // Shareaza is free software; you can redistribute it 00008 // and/or modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 of 00010 // the License, or (at your option) any later version. 00011 // 00012 // Shareaza is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU General Public License 00018 // along with Shareaza; if not, write to the Free Software 00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 // 00021 00022 // CNeighbour is in the middle of the CConnection inheritance tree, adding compression and a bunch of member variables 00023 // http://wiki.shareaza.com/static/Developers.Code.CNeighbour 00024 00025 // Make the compiler only include the lines here once, this is the same thing as pragma once 00026 #if !defined(AFX_NEIGHBOUR_H__7B1C7637_2718_4D5F_B39D_28894CC0669D__INCLUDED_) 00027 #define AFX_NEIGHBOUR_H__7B1C7637_2718_4D5F_B39D_28894CC0669D__INCLUDED_ 00028 00029 // Only include the lines beneath this one once 00030 #pragma once 00031 00032 // Copy in the contents of these files here before compiling 00033 #include "Connection.h" 00034 00035 // Tell the compiler these classes exist, and it will find out more about them soon 00036 class CBuffer; 00037 class CPacket; 00038 class CVendor; 00039 class CGProfile; 00040 class CQuerySearch; 00041 class CQueryHashTable; 00042 00043 // Keep track of what stage of communications we are in with the remote computer 00044 typedef enum NeighbourStateEnum 00045 { 00046 // One of these states describes what's happening with our connection to the remote computer right now 00047 nrsNull, // No state recorded yet, the CNeighbour constructor sets m_nState to nrsNull 00048 nrsConnecting, // We called CConnection::ConnectTo, and are now waiting for the remote computer to do something 00049 nrsHandshake1, // We've finished sending a group of headers, and await the response 00050 nrsHandshake2, // We're reading the initial header group the remote computer has sent 00051 nrsHandshake3, // We're reading the final header group from the remote computer 00052 nrsRejected, // The remote computer started with "GNUTELLA/0.6", but did not say "200 OK" 00053 nrsClosing, // We called DelayClose to send buffered data and then close the socket connection 00054 nrsConnected // The handshake is over, the CNeighbour copy constructor sets m_nState to nrsConnected 00055 00056 } NrsState; 00057 00058 // Record if the remote computer is in the same network role as us, or in a higher or lower one 00059 typedef enum NeighbourNodeEnum 00060 { 00061 // The remote computer can be a leaf, or an ultrapeer or hub, and so can we 00062 ntNode, // We are both Gnutella ultrapeers or Gnutella2 hubs 00063 ntHub, // We are a leaf, and this connection is to a Gnutella ultrapeer or Gnutella2 hub above us 00064 ntLeaf // We are a Gnutella ultrapeer or Gnutella2 hub, and this connection is to a leaf below us 00065 00066 } NrsNode; 00067 00068 // Make the m_nPongNeeded buffer an array of 32 bytes 00069 #define PONG_NEEDED_BUFFER 32 00070 00071 // Define the CNeighbour class to inherit from CConnection, picking up a socket and methods to connect it and read data through it 00072 class CNeighbour : public CConnection 00073 { 00074 00075 // Construction 00076 public: 00077 00078 CNeighbour(PROTOCOLID nProtocol); 00079 CNeighbour(PROTOCOLID nProtocol, CNeighbour* pBase); 00080 virtual ~CNeighbour(); 00081 00082 // Attributes: State 00083 public: 00084 00085 DWORD m_nRunCookie; 00086 DWORD m_zStart; 00087 DWORD m_nUnique; 00088 PROTOCOLID m_nProtocol; 00089 NrsState m_nState; // Neighbour state, like connecting, handshake 1, 2, or 3, or rejected 00090 CVendor* m_pVendor; 00091 BOOL m_bGUID; 00092 GGUID m_pGUID; 00093 CGProfile* m_pProfile; 00094 GGUID* m_pMoreResultsGUID; //Last search GUID- used to get more results 00095 00096 // Attributes: Capabilities 00097 public: 00098 00099 BOOL m_bAutomatic; 00100 BOOL m_bShareaza; // True if the remote computer is running Shareaza also 00101 NrsNode m_nNodeType; // This connection is to a hub above us, ntHub, a leaf below us, ntLeaf, or a hub just like us, ntNode 00102 BOOL m_bQueryRouting; 00103 BOOL m_bPongCaching; 00104 BOOL m_bVendorMsg; // True if the remote computer told us it supports vendor-specific messages 00105 BOOL m_bGGEP; 00106 DWORD m_tLastQuery; // The time we last got a query packet, recorded as the number of seconds since 1970 00107 BOOL m_bObsoleteClient; // Is the remote client running an 'old' version of software. (An old beta, etc) 00108 BOOL m_bBadClient; // Is the remote client running a 'bad' client- GPL rip, buggy, etc. (not banned, though) 00109 00110 // Attributes: Statistics 00111 public: 00112 00113 DWORD m_nInputCount; 00114 DWORD m_nOutputCount; 00115 DWORD m_nDropCount; 00116 DWORD m_nLostCount; 00117 DWORD m_nOutbound; 00118 00119 // If the remote computer sends us a pong packet it made, copy the sharing statistics here 00120 DWORD m_nFileCount; // The number of files the remote computer is sharing, according to the pong packet it sent us 00121 DWORD m_nFileVolume; // The total size of all of those files, according to the same pong packet 00122 00123 // Attributes: Query Hash Tables 00124 public: 00125 00126 CQueryHashTable* m_pQueryTableRemote; 00127 CQueryHashTable* m_pQueryTableLocal; 00128 00129 // Attributes: Internals 00130 protected: 00131 00132 DWORD m_tLastPacket; // The time that we received the last packet 00133 CBuffer* m_pZInput; // The remote computer is sending compressed data, we'll save it in m_pInput, and then decompress it to here 00134 CBuffer* m_pZOutput; // We are sending the remote computer compressed data, we're writing it here, and then compressing it to m_pOutput 00135 DWORD m_nZInput; // The number of decompressed bytes of data the remote computer sent us 00136 DWORD m_nZOutput; // The number of not yet compressed bytes of data we've sent the remote computer 00137 LPVOID m_pZSInput; // Pointer to the zlib z_stream structure for decompression 00138 LPVOID m_pZSOutput; // Pointer to the zlib z_stream structure for compression 00139 BOOL m_bZFlush; // True to flush the compressed output buffer to the remote computer 00140 DWORD m_tZOutput; // The time that Zlib last compressed something 00141 00142 protected: 00143 00144 DWORD m_zEnd; 00145 00146 // Operations 00147 public: 00148 00149 virtual BOOL Send(CPacket* pPacket, BOOL bRelease = TRUE, BOOL bBuffered = FALSE); 00150 virtual void Close(UINT nError = IDS_CONNECTION_CLOSED); 00151 void DelayClose(UINT nError = 0); // Send the buffer then close the socket, record the error given 00152 virtual BOOL SendQuery(CQuerySearch* pSearch, CPacket* pPacket, BOOL bLocal); 00153 00154 protected: 00155 00156 virtual BOOL OnRun(); 00157 virtual void OnDropped(BOOL bError); 00158 virtual BOOL OnRead(); 00159 virtual BOOL OnWrite(); 00160 virtual BOOL OnCommonHit(CPacket* pPacket); 00161 virtual BOOL OnCommonQueryHash(CPacket* pPacket); 00162 00163 public: 00164 00165 void GetCompression(float* pnInRate, float* pnOutRate); 00166 }; 00167 00168 // End the group of lines to only include once, pragma once doesn't require an endif at the bottom 00169 #endif // !defined(AFX_NEIGHBOUR_H__7B1C7637_2718_4D5F_B39D_28894CC0669D__INCLUDED_)