1 // ------------------------------------------------
7 // (c) 2002 peercast.org
8 // ------------------------------------------------
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 // ------------------------------------------------
24 // ----------------------------------
37 // ----------------------------------
38 // Servent handles the actual connection between clients
45 MAX_HASH = 500, // max. amount of packet hashes Servents can store
46 MAX_OUTPACKETS = 32 // max. output packets per queue (normal/priority)
51 MAX_PROC_PACKETS = 300,
52 MAX_OUTWARD_SIZE = 1024 * 10
57 T_NONE, // Not allocated
58 T_INCOMING, // Unknown incoming
59 T_SERVER, // The main server
60 T_RELAY, // Outgoing relay
61 T_DIRECT, // Outgoing direct connection
62 T_COUT, // PCP out connection
63 T_CIN, // PCP in connection
64 T_PGNU // old protocol connection
105 ALLOW_BROADCAST = 0x02,
106 ALLOW_NETWORK = 0x04,
115 bool initServer(Host &);
116 void initIncoming(ClientSocket *,unsigned int);
117 void initOutgoing(TYPE);
118 void initGIV(Host &, GnuID &);
119 void initPCP(Host &);
126 // funcs for handling status/type
127 void setStatus(STATUS);
128 static char * getTypeStr(Servent::TYPE t) {return typeMsgs[t];}
129 char * getTypeStr() {return getTypeStr(type);}
130 char * getStatusStr() {return statusMsgs[status];}
132 void addBytes(unsigned int);
133 bool isOlderThan(Servent *s)
137 unsigned int t = sys->getTime();
138 return ((t-lastConnect) > (t-s->lastConnect));
145 // static funcs that do the actual work in the servent thread
146 static THREAD_PROC serverProc(ThreadInfo *);
147 static THREAD_PROC serverProcMain(ThreadInfo *);
148 static THREAD_PROC outgoingProc(ThreadInfo *);
149 static THREAD_PROC outgoingProcMain(ThreadInfo *);
150 static THREAD_PROC incomingProc(ThreadInfo *);
151 static THREAD_PROC incomingProcMain(ThreadInfo *);
152 static THREAD_PROC givProc(ThreadInfo *);
153 static THREAD_PROC givProcMain(ThreadInfo *);
154 static THREAD_PROC pcpProc(ThreadInfo *);
155 static THREAD_PROC fetchProc(ThreadInfo *);
157 static bool pingHost(Host &,GnuID &);
159 bool getLocalURL(char *);
160 bool getLocalTypeURL(char *, ChanInfo::TYPE);
162 // various types of handshaking are needed
163 void handshakePLS(ChanHitList **, int, bool);
164 void handshakePLS(ChanInfo &, bool);
166 void handshakeHTML(char *);
168 void handshakeCMD(char *);
169 bool handshakeAuth(HTTP &,const char *,bool);
174 void processOutPCP();
175 void processOutChannel();
177 bool handshakeStream(ChanInfo &);
178 void handshakeGiv(GnuID &);
180 void handshakeICY(Channel::SRC_TYPE,bool);
181 void handshakeIncoming();
182 void handshakePOST();
183 void handshakeRTSP(RTSP &);
184 void handshakeHTTP(HTTP &,bool);
186 void handshakeRemoteFile(const char *);
187 void handshakeLocalFile(const char *);
189 static void handshakeOutgoingPCP(AtomStream &,Host &,GnuID &,String &,bool);
190 static void handshakeIncomingPCP(AtomStream &,Host &,GnuID &,String &);
192 void processIncomingPCP(bool);
194 bool waitForChannelHeader(ChanInfo &);
195 ChanInfo findChannel(char *str,ChanInfo &);
197 bool writeVariable(Stream &, const String &);
200 // the "mainloop" of servents
201 void processGnutella();
203 void processServent();
204 void processStream(bool,ChanInfo &);
205 void processPCP(bool,bool);
207 bool procAtoms(AtomStream &);
208 void procRootAtoms(AtomStream &,int);
209 void procHeloAtoms(AtomStream &,int,bool);
210 void procGetAtoms(AtomStream &,int);
212 void triggerChannel(char *,ChanInfo::PROTOCOL,bool);
213 void sendPeercastChannel();
214 void sendRawChannel(bool,bool);
215 // void sendRawMultiChannel(bool,bool);
216 void sendRawMetaChannel(int);
217 void sendPCPChannel();
218 void checkPCPComms(Channel *, AtomStream &);
220 static void readICYHeader(HTTP &, ChanInfo &, char *, size_t);
221 bool canStream(Channel *);
223 bool isConnected() {return status == S_CONNECTED;}
224 bool isListening() {return status == S_LISTENING;}
227 bool isFiltered(int);
229 // connection handling funcs
239 bool outputPacket(GnuPacket &,bool);
240 bool hasSeenPacket(GnuPacket &p) {return seenIDs.contains(p.id);}
241 bool acceptGIV(ClientSocket *);
242 bool sendPacket(ChanPacket &,GnuID &,GnuID &,GnuID &,Servent::TYPE);
248 static char *statusMsgs[],*typeMsgs[];
251 unsigned int lastConnect,lastPing,lastPacket;
267 String loginPassword;
270 bool priorityConnect;
276 ClientSocket *sock,*pushSock;
281 unsigned int syncPos,streamPos;
284 ChanInfo::PROTOCOL outputProtocol;
286 GnuPacketBuffer outPacketsNorm,outPacketsPri;
288 unsigned int bytesPerSecond;
293 PCPStream *pcpStream;
297 unsigned int lastSkipTime;
298 unsigned int lastSkipCount;
299 unsigned int waitPort;
306 extern char *nextCGIarg(char *cp, char *cmd, char *arg);