1 // ------------------------------------------------
6 // Management class for handling multiple servent connections.
8 // (c) 2002 peercast.org
9 // ------------------------------------------------
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 // ------------------------------------------------
31 #include "chkMemoryLeak.h"
32 #define DEBUG_NEW new(__FILE__, __LINE__)
36 ThreadInfo ServMgr::serverThread,ServMgr::idleThread;
38 // -----------------------------------
43 authType = AUTH_COOKIE;
48 startTime = sys->getTime();
50 allowServer1 = Servent::ALLOW_ALL;
51 allowServer2 = Servent::ALLOW_BROADCAST;
53 clearHostCache(ServHost::T_NONE);
56 allowGnutella = false;
57 useFlowControl = true;
65 maxBitrateOut = 540; //JP-Patch 0-> 540
66 maxRelays = MIN_RELAYS;
84 strcpy(connectHost,"connect1.peercast.org");
85 strcpy(htmlPath,"html/ja");
87 rootHost = "yp.peercast.org";
90 serverHost.fromStrIP("127.0.0.1",DEFAULT_PORT);
92 firewalled = FW_UNKNOWN;
104 firewallTimeout = 30;
120 modulePath[0] = 0; //JP-EX
121 kickPushStartRelays = 1; //JP-EX
122 kickPushInterval = 60; //JP-EX
123 kickPushTime = 0; //JP-EX
124 autoRelayKeep = 2; //JP-EX
125 autoMaxRelaySetting = 0; //JP-EX
126 autoBumpSkipCount = 50; //JP-EX
127 enableGetName = 1; //JP-EX
128 allowConnectPCST = 0; //JP-EX
129 getModulePath = true; //JP-EX
130 clearPLS = false; //JP-EX
131 writeLogFile = false; //JP-EX
133 autoPort0Kick = false;
137 saveIniChannel = true;
139 keepDownstreams = true;
142 startWithGui = false;
146 maxRelaysIndexTxt = 1; // for PCRaw (relay)
148 // -----------------------------------
149 BCID *ServMgr::findValidBCID(int index)
152 BCID *bcid = validBCID;
162 // -----------------------------------
163 BCID *ServMgr::findValidBCID(GnuID &id)
165 BCID *bcid = validBCID;
168 if (bcid->id.isSame(id))
174 // -----------------------------------
175 void ServMgr::removeValidBCID(GnuID &id)
177 BCID *bcid = validBCID,*prev=0;
180 if (bcid->id.isSame(id))
183 prev->next = bcid->next;
185 validBCID = bcid->next;
192 // -----------------------------------
193 void ServMgr::addValidBCID(BCID *bcid)
195 removeValidBCID(bcid->id);
197 bcid->next = validBCID;
201 // -----------------------------------
202 void ServMgr::connectBroadcaster()
204 if (!rootHost.isEmpty())
206 if (!numUsed(Servent::T_COUT))
208 Servent *sv = allocServent();
211 sv->initOutgoing(Servent::T_COUT);
217 // -----------------------------------
218 void ServMgr::addVersion(unsigned int ver)
220 for(int i=0; i<numVersions; i++)
221 if (clientVersions[i] == ver)
227 if (numVersions < MAX_VERSIONS)
229 clientVersions[numVersions] = ver;
230 clientCounts[numVersions] = 1;
235 // -----------------------------------
236 void ServMgr::setFilterDefaults()
240 filters[numFilters].host.fromStrIP("255.255.255.255",0);
241 // filters[numFilters].flags = ServFilter::F_NETWORK|ServFilter::F_DIRECT;
242 filters[numFilters].flags = ServFilter::F_NETWORK;
248 // -----------------------------------
249 void ServMgr::setPassiveSearch(unsigned int t)
251 // if ((t > 0) && (t < 60))
253 // passiveSearch = t;
255 // -----------------------------------
256 bool ServMgr::seenHost(Host &h, ServHost::TYPE type,unsigned int time)
258 time = sys->getTime()-time;
260 for(int i=0; i<MAX_HOSTCACHE; i++)
261 if (hostCache[i].type == type)
262 if (hostCache[i].host.ip == h.ip)
263 if (hostCache[i].time >= time)
268 // -----------------------------------
269 void ServMgr::addHost(Host &h, ServHost::TYPE type, unsigned int time)
277 for(i=0; i<MAX_HOSTCACHE; i++)
278 if (hostCache[i].type == type)
279 if (hostCache[i].host.isSame(h))
289 LOG_DEBUG("New host: %s - %s",str,ServHost::getTypeStr(type));
291 LOG_DEBUG("Old host: %s - %s",str,ServHost::getTypeStr(type));
293 h.value = 0; // make sure dead count is zero
299 for(i=0; i<MAX_HOSTCACHE; i++)
300 if (hostCache[i].type == ServHost::T_NONE)
306 // otherwise, find oldest host and replace
308 for(i=0; i<MAX_HOSTCACHE; i++)
309 if (hostCache[i].type != ServHost::T_NONE)
313 if (hostCache[i].time < sh->time)
322 sh->init(h,type,time);
325 // -----------------------------------
326 void ServMgr::deadHost(Host &h,ServHost::TYPE t)
328 for(int i=0; i<MAX_HOSTCACHE; i++)
329 if (hostCache[i].type == t)
330 if (hostCache[i].host.ip == h.ip)
331 if (hostCache[i].host.port == h.port)
334 // -----------------------------------
335 void ServMgr::clearHostCache(ServHost::TYPE type)
337 for(int i=0; i<MAX_HOSTCACHE; i++)
338 if ((hostCache[i].type == type) || (type == ServHost::T_NONE))
342 // -----------------------------------
343 unsigned int ServMgr::numHosts(ServHost::TYPE type)
345 unsigned int cnt = 0;
346 for(int i=0; i<MAX_HOSTCACHE; i++)
347 if ((hostCache[i].type == type) || (type == ServHost::T_NONE))
351 // -----------------------------------
352 int ServMgr::getNewestServents(Host *hl,int max,Host &rh)
355 for(int i=0; i<max; i++)
357 // find newest host not in list
359 for(int j=0; j<MAX_HOSTCACHE; j++)
361 // find newest servent
362 if (hostCache[j].type == ServHost::T_SERVENT)
363 if (!(rh.globalIP() && !hostCache[j].host.globalIP()))
365 // and not in list already
367 for(int k=0; k<cnt; k++)
368 if (hl[k].isSame(hostCache[j].host))
380 if (hostCache[j].time > sh->time)
394 // -----------------------------------
395 ServHost ServMgr::getOutgoingServent(GnuID &netid)
399 Host lh(ClientSocket::getIP(NULL),0);
401 // find newest host not in list
403 for(int j=0; j<MAX_HOSTCACHE; j++)
405 ServHost *hc=&hostCache[j];
406 // find newest servent not already connected.
407 if (hc->type == ServHost::T_SERVENT)
409 if (!((lh.globalIP() && !hc->host.globalIP()) || lh.isSame(hc->host)))
412 if (!findServent(Servent::T_OUTGOING,hc->host,netid))
418 if (hc->time > sh->time)
432 // -----------------------------------
433 Servent *ServMgr::findOldestServent(Servent::TYPE type, bool priv)
435 Servent *oldest=NULL;
437 Servent *s = servents;
441 if (s->thread.active)
442 if (s->isOlderThan(oldest))
443 if (s->isPrivate() == priv)
449 // -----------------------------------
450 Servent *ServMgr::findServent(Servent::TYPE type, Host &host, GnuID &netid)
453 Servent *s = servents;
458 Host h = s->getHost();
459 if (h.isSame(host) && s->networkID.isSame(netid))
472 // -----------------------------------
473 Servent *ServMgr::findServent(unsigned int ip, unsigned short port, GnuID &netid)
476 Servent *s = servents;
479 if (s->type != Servent::T_NONE)
481 Host h = s->getHost();
482 if ((h.ip == ip) && (h.port == port) && (s->networkID.isSame(netid)))
495 // -----------------------------------
496 Servent *ServMgr::findServent(Servent::TYPE t)
498 Servent *s = servents;
507 // -----------------------------------
508 Servent *ServMgr::findServentByIndex(int id)
510 Servent *s = servents;
522 // -----------------------------------
523 Servent *ServMgr::findServentByServentID(int id)
525 Servent *s = servents;
528 if (id == s->servent_id){
536 // -----------------------------------
537 Servent *ServMgr::allocServent()
541 Servent *s = servents;
544 if (s->status == Servent::S_FREE)
551 s = new Servent(++serventNum);
555 LOG_DEBUG("allocated servent %d",serventNum);
557 LOG_DEBUG("reused servent %d",s->serventIndex);
566 // --------------------------------------------------
567 void ServMgr::closeConnections(Servent::TYPE type)
569 Servent *sv = servents;
572 if (sv->isConnected())
573 if (sv->type == type)
574 sv->thread.active = false;
579 // -----------------------------------
580 unsigned int ServMgr::numConnected(int type,bool priv,unsigned int uptime)
584 unsigned int ctime=sys->getTime();
585 Servent *s = servents;
588 if (s->thread.active)
589 if (s->isConnected())
591 if (s->isPrivate()==priv)
592 if ((ctime-s->lastConnect) >= uptime)
599 // -----------------------------------
600 unsigned int ServMgr::numConnected()
604 Servent *s = servents;
607 if (s->thread.active)
608 if (s->isConnected())
615 // -----------------------------------
616 unsigned int ServMgr::numServents()
620 Servent *s = servents;
629 // -----------------------------------
630 unsigned int ServMgr::numUsed(int type)
634 Servent *s = servents;
643 // -----------------------------------
644 unsigned int ServMgr::numActiveOnPort(int port)
648 Servent *s = servents;
651 if (s->thread.active && s->sock && (s->servPort == port))
657 // -----------------------------------
658 unsigned int ServMgr::numActive(Servent::TYPE tp)
662 Servent *s = servents;
665 if (s->thread.active && s->sock && (s->type == tp))
672 // -----------------------------------
673 unsigned int ServMgr::totalOutput(bool all)
675 unsigned int tot = 0;
676 Servent *s = servents;
679 if (s->isConnected())
680 if (all || !s->isPrivate())
682 tot += s->sock->bytesOutPerSec;
689 // -----------------------------------
690 unsigned int ServMgr::totalInput(bool all)
692 unsigned int tot = 0;
693 Servent *s = servents;
696 if (s->isConnected())
697 if (all || !s->isPrivate())
699 tot += s->sock->bytesInPerSec;
706 // -----------------------------------
707 unsigned int ServMgr::numOutgoing()
711 Servent *s = servents;
714 // if ((s->type == Servent::T_INCOMING) ||
715 // (s->type == Servent::T_OUTGOING))
722 // -----------------------------------
723 bool ServMgr::seenPacket(GnuPacket &p)
725 Servent *s = servents;
728 if (s->isConnected())
729 if (s->seenIDs.contains(p.id))
736 // -----------------------------------
739 LOG_DEBUG("ServMgr is quitting..");
741 serverThread.shutdown();
743 idleThread.shutdown();
745 Servent *s = servents;
750 if (s->thread.active)
752 s->thread.shutdown();
755 }catch(StreamException &)
762 // -----------------------------------
763 int ServMgr::broadcast(GnuPacket &pack,Servent *src)
768 Servent *s = servents;
773 if (s->isConnected())
774 if (s->type == Servent::T_PGNU)
775 if (!s->seenIDs.contains(pack.id))
779 if (!src->networkID.isSame(s->networkID))
782 if (s->outputPacket(pack,false))
789 LOG_NETWORK("broadcast: %s (%d) to %d servents",GNU_FUNC_STR(pack.func),pack.ttl,cnt);
793 // -----------------------------------
794 int ServMgr::route(GnuPacket &pack, GnuID &routeID, Servent *src)
799 Servent *s = servents;
803 if (s->isConnected())
804 if (s->type == Servent::T_PGNU)
805 if (!s->seenIDs.contains(pack.id))
806 if (s->seenIDs.contains(routeID))
809 if (!src->networkID.isSame(s->networkID))
812 if (s->outputPacket(pack,true))
820 LOG_NETWORK("route: %s (%d) to %d servents",GNU_FUNC_STR(pack.func),pack.ttl,cnt);
823 // -----------------------------------
824 bool ServMgr::checkForceIP()
826 if (!forceIP.isEmpty())
828 unsigned int newIP = ClientSocket::getIP(forceIP.cstr());
829 if (serverHost.ip != newIP)
831 serverHost.ip = newIP;
833 serverHost.IPtoStr(ipstr);
834 LOG_DEBUG("Server IP changed to %s",ipstr);
841 // -----------------------------------
842 void ServMgr::checkFirewall()
844 if ((getFirewall() == FW_UNKNOWN) && !servMgr->rootHost.isEmpty())
847 LOG_DEBUG("Checking firewall..");
849 host.fromStrName(servMgr->rootHost.cstr(),DEFAULT_PORT);
851 ClientSocket *sock = sys->createSocket();
853 throw StreamException("Unable to create socket");
854 sock->setReadTimeout(30000);
858 AtomStream atom(*sock);
860 atom.writeInt(PCP_CONNECT,1);
864 Servent::handshakeOutgoingPCP(atom,sock->host,remoteID,agent,true);
866 atom.writeInt(PCP_QUIT,PCP_ERROR_QUIT);
873 // -----------------------------------
874 void ServMgr::setFirewall(FW_STATE state)
876 if (firewalled != state)
893 LOG_DEBUG("Firewall is set to %s",str);
897 // -----------------------------------
898 bool ServMgr::isFiltered(int fl, Host &h)
900 for(int i=0; i<numFilters; i++)
901 if (filters[i].flags & fl)
902 if (h.isMemberOf(filters[i].host))
909 // -----------------------------------
910 bool ServMgr::canServeHost(Host &h)
914 Host sh = server->getHost();
916 if (sh.globalIP() || (sh.localIP() && h.localIP()))
923 // --------------------------------------------------
924 void writeServerSettings(IniFile &iniFile, unsigned int a)
926 iniFile.writeBoolValue("allowHTML",a & Servent::ALLOW_HTML);
927 iniFile.writeBoolValue("allowBroadcast",a & Servent::ALLOW_BROADCAST);
928 iniFile.writeBoolValue("allowNetwork",a & Servent::ALLOW_NETWORK);
929 iniFile.writeBoolValue("allowDirect",a & Servent::ALLOW_DIRECT);
931 // --------------------------------------------------
932 void writeFilterSettings(IniFile &iniFile, ServFilter &f)
935 f.host.IPtoStr(ipstr);
936 iniFile.writeStrValue("ip",ipstr);
937 iniFile.writeBoolValue("private",f.flags & ServFilter::F_PRIVATE);
938 iniFile.writeBoolValue("ban",f.flags & ServFilter::F_BAN);
939 iniFile.writeBoolValue("network",f.flags & ServFilter::F_NETWORK);
940 iniFile.writeBoolValue("direct",f.flags & ServFilter::F_DIRECT);
943 // --------------------------------------------------
944 static void writeServHost(IniFile &iniFile, ServHost &sh)
946 iniFile.writeSection("Host");
949 sh.host.toStr(ipStr);
950 iniFile.writeStrValue("type",ServHost::getTypeStr(sh.type));
951 iniFile.writeStrValue("address",ipStr);
952 iniFile.writeIntValue("time",sh.time);
954 iniFile.writeLine("[End]");
959 extern WINDOWPLACEMENT winPlace;
963 // --------------------------------------------------
964 void ServMgr::saveSettings(const char *fn)
967 if (!iniFile.openWriteReplace(fn))
969 LOG_ERROR("Unable to open ini file");
971 LOG_DEBUG("Saving settings to: %s",fn);
975 iniFile.writeSection("Server");
976 iniFile.writeIntValue("serverPort",servMgr->serverHost.port);
977 iniFile.writeBoolValue("autoServe",servMgr->autoServe);
978 iniFile.writeStrValue("forceIP",servMgr->forceIP);
979 iniFile.writeBoolValue("isRoot",servMgr->isRoot);
980 iniFile.writeIntValue("maxBitrateOut",servMgr->maxBitrateOut);
981 iniFile.writeIntValue("maxRelays",servMgr->maxRelays);
982 iniFile.writeIntValue("maxDirect",servMgr->maxDirect);
983 iniFile.writeIntValue("maxRelaysPerChannel",chanMgr->maxRelaysPerChannel);
984 iniFile.writeIntValue("firewallTimeout",firewallTimeout);
985 iniFile.writeBoolValue("forceNormal",forceNormal);
986 iniFile.writeStrValue("rootMsg",rootMsg.cstr());
987 iniFile.writeStrValue("authType",servMgr->authType==ServMgr::AUTH_COOKIE?"cookie":"http-basic");
988 iniFile.writeStrValue("cookiesExpire",servMgr->cookieList.neverExpire==true?"never":"session");
989 iniFile.writeStrValue("htmlPath",servMgr->htmlPath);
990 iniFile.writeIntValue("minPGNUIncoming",servMgr->minGnuIncoming);
991 iniFile.writeIntValue("maxPGNUIncoming",servMgr->maxGnuIncoming);
992 iniFile.writeIntValue("maxServIn",servMgr->maxServIn);
993 iniFile.writeStrValue("chanLog",servMgr->chanLog.cstr());
995 networkID.toStr(idStr);
996 iniFile.writeStrValue("networkID",idStr);
999 iniFile.writeSection("Broadcast");
1000 iniFile.writeIntValue("broadcastMsgInterval",chanMgr->broadcastMsgInterval);
1001 iniFile.writeStrValue("broadcastMsg",chanMgr->broadcastMsg.cstr());
1002 iniFile.writeIntValue("icyMetaInterval",chanMgr->icyMetaInterval);
1003 chanMgr->broadcastID.toStr(idStr);
1004 iniFile.writeStrValue("broadcastID",idStr);
1005 iniFile.writeIntValue("hostUpdateInterval",chanMgr->hostUpdateInterval);
1006 iniFile.writeIntValue("maxControlConnections",servMgr->maxControl);
1007 iniFile.writeStrValue("rootHost",servMgr->rootHost.cstr());
1009 iniFile.writeSection("Client");
1010 iniFile.writeIntValue("refreshHTML",refreshHTML);
1011 iniFile.writeIntValue("relayBroadcast",servMgr->relayBroadcast);
1012 iniFile.writeIntValue("minBroadcastTTL",chanMgr->minBroadcastTTL);
1013 iniFile.writeIntValue("maxBroadcastTTL",chanMgr->maxBroadcastTTL);
1014 iniFile.writeIntValue("pushTries",chanMgr->pushTries);
1015 iniFile.writeIntValue("pushTimeout",chanMgr->pushTimeout);
1016 iniFile.writeIntValue("maxPushHops",chanMgr->maxPushHops);
1017 iniFile.writeIntValue("autoQuery",chanMgr->autoQuery);
1018 iniFile.writeIntValue("queryTTL",servMgr->queryTTL);
1021 iniFile.writeSection("Privacy");
1022 iniFile.writeStrValue("password",servMgr->password);
1023 iniFile.writeIntValue("maxUptime",chanMgr->maxUptime);
1026 iniFile.writeSection("Extend");
1027 iniFile.writeIntValue("autoRelayKeep",servMgr->autoRelayKeep);
1028 iniFile.writeIntValue("autoMaxRelaySetting",servMgr->autoMaxRelaySetting);
1029 iniFile.writeIntValue("autoBumpSkipCount",servMgr->autoBumpSkipCount);
1030 iniFile.writeIntValue("kickPushStartRelays",servMgr->kickPushStartRelays);
1031 iniFile.writeIntValue("kickPushInterval",servMgr->kickPushInterval);
1032 iniFile.writeIntValue("allowConnectPCST",servMgr->allowConnectPCST);
1033 iniFile.writeIntValue("enableGetName",servMgr->enableGetName);
1035 iniFile.writeIntValue("maxRelaysIndexTxt", servMgr->maxRelaysIndexTxt); // for PCRaw (relay)
1038 iniFile.writeSection("Windows");
1039 iniFile.writeBoolValue("getModulePath",servMgr->getModulePath);
1040 iniFile.writeBoolValue("clearPLS",servMgr->clearPLS);
1041 iniFile.writeBoolValue("writeLogFile",servMgr->writeLogFile);
1044 iniFile.writeStrValue("rootHost2",servMgr->rootHost2.cstr());
1045 iniFile.writeBoolValue("autoPort0Kick",servMgr->autoPort0Kick);
1046 iniFile.writeBoolValue("allowOnlyVP",servMgr->allowOnlyVP);
1047 iniFile.writeIntValue("kickKeepTime",servMgr->kickKeepTime);
1048 iniFile.writeBoolValue("vpDebug", servMgr->vpDebug);
1049 iniFile.writeBoolValue("saveIniChannel", servMgr->saveIniChannel);
1051 iniFile.writeBoolValue("saveGuiPos", servMgr->saveGuiPos);
1053 GetWindowPlacement(guiWnd, &winPlace);
1054 iniFile.writeIntValue("guiTop", winPlace.rcNormalPosition.top);
1055 iniFile.writeIntValue("guiBottom", winPlace.rcNormalPosition.bottom);
1056 iniFile.writeIntValue("guiLeft", winPlace.rcNormalPosition.left);
1057 iniFile.writeIntValue("guiRight", winPlace.rcNormalPosition.right);
1060 iniFile.writeBoolValue("topmostGui", servMgr->topmostGui);
1061 iniFile.writeBoolValue("startWithGui", servMgr->startWithGui);
1065 for(i=0; i<servMgr->numFilters; i++)
1067 iniFile.writeSection("Filter");
1068 writeFilterSettings(iniFile,servMgr->filters[i]);
1069 iniFile.writeLine("[End]");
1072 iniFile.writeSection("Notify");
1073 iniFile.writeBoolValue("PeerCast",notifyMask&NT_PEERCAST);
1074 iniFile.writeBoolValue("Broadcasters",notifyMask&NT_BROADCASTERS);
1075 iniFile.writeBoolValue("TrackInfo",notifyMask&NT_TRACKINFO);
1076 iniFile.writeLine("[End]");
1079 iniFile.writeSection("Server1");
1080 writeServerSettings(iniFile,allowServer1);
1081 iniFile.writeLine("[End]");
1083 iniFile.writeSection("Server2");
1084 writeServerSettings(iniFile,allowServer2);
1085 iniFile.writeLine("[End]");
1089 iniFile.writeSection("Debug");
1090 iniFile.writeBoolValue("logDebug",(showLog&(1<<LogBuffer::T_DEBUG))!=0);
1091 iniFile.writeBoolValue("logErrors",(showLog&(1<<LogBuffer::T_ERROR))!=0);
1092 iniFile.writeBoolValue("logNetwork",(showLog&(1<<LogBuffer::T_NETWORK))!=0);
1093 iniFile.writeBoolValue("logChannel",(showLog&(1<<LogBuffer::T_CHANNEL))!=0);
1094 iniFile.writeBoolValue("pauseLog",pauseLog);
1095 iniFile.writeIntValue("idleSleepTime",sys->idleSleepTime);
1098 if (servMgr->validBCID)
1100 BCID *bcid = servMgr->validBCID;
1103 iniFile.writeSection("ValidBCID");
1105 bcid->id.toStr(idstr);
1106 iniFile.writeStrValue("id",idstr);
1107 iniFile.writeStrValue("name",bcid->name.cstr());
1108 iniFile.writeStrValue("email",bcid->email.cstr());
1109 iniFile.writeStrValue("url",bcid->url.cstr());
1110 iniFile.writeBoolValue("valid",bcid->valid);
1111 iniFile.writeLine("[End]");
1117 if (servMgr->saveIniChannel){
1118 Channel *c = chanMgr->channel;
1122 if (c->isActive() && c->stayConnected)
1126 iniFile.writeSection("RelayChannel");
1127 iniFile.writeStrValue("name",c->getName());
1128 iniFile.writeStrValue("genre",c->info.genre.cstr());
1129 if (!c->sourceURL.isEmpty())
1130 iniFile.writeStrValue("sourceURL",c->sourceURL.cstr());
1131 iniFile.writeStrValue("sourceProtocol",ChanInfo::getProtocolStr(c->info.srcProtocol));
1132 iniFile.writeStrValue("contentType",ChanInfo::getTypeStr(c->info.contentType));
1133 iniFile.writeIntValue("bitrate",c->info.bitrate);
1134 iniFile.writeStrValue("contactURL",c->info.url.cstr());
1135 iniFile.writeStrValue("id",idstr);
1136 iniFile.writeBoolValue("stayConnected",c->stayConnected);
1138 ChanHitList *chl = chanMgr->findHitListByID(c->info.id);
1143 chs.trackersOnly = true;
1144 if (chl->pickHits(chs))
1147 chs.best[0].host.toStr(ipStr);
1148 iniFile.writeStrValue("tracker",ipStr);
1151 iniFile.writeLine("[End]");
1160 Servent *s = servents;
1163 if (s->type == Servent::T_OUTGOING)
1164 if (s->isConnected())
1167 Host h = s->getHost();
1168 sh.init(h,ServHost::T_SERVENT,0,s->networkID);
1169 writeServHost(iniFile,sh);
1175 for(i=0; i<ServMgr::MAX_HOSTCACHE; i++)
1177 ServHost *sh = &servMgr->hostCache[i];
1178 if (sh->type != ServHost::T_NONE)
1179 writeServHost(iniFile,*sh);
1185 // --------------------------------------------------
1186 unsigned int readServerSettings(IniFile &iniFile, unsigned int a)
1188 while (iniFile.readNext())
1190 if (iniFile.isName("[End]"))
1192 else if (iniFile.isName("allowHTML"))
1193 a = iniFile.getBoolValue()?a|Servent::ALLOW_HTML:a&~Servent::ALLOW_HTML;
1194 else if (iniFile.isName("allowDirect"))
1195 a = iniFile.getBoolValue()?a|Servent::ALLOW_DIRECT:a&~Servent::ALLOW_DIRECT;
1196 else if (iniFile.isName("allowNetwork"))
1197 a = iniFile.getBoolValue()?a|Servent::ALLOW_NETWORK:a&~Servent::ALLOW_NETWORK;
1198 else if (iniFile.isName("allowBroadcast"))
1199 a = iniFile.getBoolValue()?a|Servent::ALLOW_BROADCAST:a&~Servent::ALLOW_BROADCAST;
1203 // --------------------------------------------------
1204 void readFilterSettings(IniFile &iniFile, ServFilter &sv)
1208 while (iniFile.readNext())
1210 if (iniFile.isName("[End]"))
1212 else if (iniFile.isName("ip"))
1213 sv.host.fromStrIP(iniFile.getStrValue(),0);
1214 else if (iniFile.isName("private"))
1215 sv.flags = (sv.flags & ~ServFilter::F_PRIVATE) | (iniFile.getBoolValue()?ServFilter::F_PRIVATE:0);
1216 else if (iniFile.isName("ban"))
1217 sv.flags = (sv.flags & ~ServFilter::F_BAN) | (iniFile.getBoolValue()?ServFilter::F_BAN:0);
1218 else if (iniFile.isName("allow") || iniFile.isName("network"))
1219 sv.flags = (sv.flags & ~ServFilter::F_NETWORK) | (iniFile.getBoolValue()?ServFilter::F_NETWORK:0);
1220 else if (iniFile.isName("direct"))
1221 sv.flags = (sv.flags & ~ServFilter::F_DIRECT) | (iniFile.getBoolValue()?ServFilter::F_DIRECT:0);
1225 // --------------------------------------------------
1226 void ServMgr::loadSettings(const char *fn)
1230 if (!iniFile.openReadOnly(fn))
1234 servMgr->numFilters = 0;
1237 if (iniFile.openReadOnly(fn))
1239 while (iniFile.readNext())
1242 if (iniFile.isName("serverPort"))
1243 servMgr->serverHost.port = iniFile.getIntValue();
1244 else if (iniFile.isName("autoServe"))
1245 servMgr->autoServe = iniFile.getBoolValue();
1246 else if (iniFile.isName("autoConnect"))
1247 servMgr->autoConnect = iniFile.getBoolValue();
1248 else if (iniFile.isName("icyPassword")) // depreciated
1249 strcpy(servMgr->password,iniFile.getStrValue());
1250 else if (iniFile.isName("forceIP"))
1251 servMgr->forceIP = iniFile.getStrValue();
1252 else if (iniFile.isName("isRoot"))
1253 servMgr->isRoot = iniFile.getBoolValue();
1254 else if (iniFile.isName("broadcastID"))
1256 chanMgr->broadcastID.fromStr(iniFile.getStrValue());
1257 chanMgr->broadcastID.id[0] = PCP_BROADCAST_FLAGS; // hacky, but we need to fix old clients
1259 }else if (iniFile.isName("htmlPath"))
1260 strcpy(servMgr->htmlPath,iniFile.getStrValue());
1261 else if (iniFile.isName("maxPGNUIncoming"))
1262 servMgr->maxGnuIncoming = iniFile.getIntValue();
1263 else if (iniFile.isName("minPGNUIncoming"))
1264 servMgr->minGnuIncoming = iniFile.getIntValue();
1266 else if (iniFile.isName("maxControlConnections"))
1268 servMgr->maxControl = iniFile.getIntValue();
1271 else if (iniFile.isName("maxBitrateOut"))
1272 servMgr->maxBitrateOut = iniFile.getIntValue();
1274 else if (iniFile.isName("maxStreamsOut")) // depreciated
1275 servMgr->setMaxRelays(iniFile.getIntValue());
1276 else if (iniFile.isName("maxRelays"))
1277 servMgr->setMaxRelays(iniFile.getIntValue());
1278 else if (iniFile.isName("maxDirect"))
1279 servMgr->maxDirect = iniFile.getIntValue();
1281 else if (iniFile.isName("maxStreamsPerChannel")) // depreciated
1282 chanMgr->maxRelaysPerChannel = iniFile.getIntValue();
1283 else if (iniFile.isName("maxRelaysPerChannel"))
1284 chanMgr->maxRelaysPerChannel = iniFile.getIntValue();
1286 else if (iniFile.isName("firewallTimeout"))
1287 firewallTimeout = iniFile.getIntValue();
1288 else if (iniFile.isName("forceNormal"))
1289 forceNormal = iniFile.getBoolValue();
1290 else if (iniFile.isName("broadcastMsgInterval"))
1291 chanMgr->broadcastMsgInterval = iniFile.getIntValue();
1292 else if (iniFile.isName("broadcastMsg"))
1293 chanMgr->broadcastMsg.set(iniFile.getStrValue(),String::T_ASCII);
1294 else if (iniFile.isName("hostUpdateInterval"))
1295 chanMgr->hostUpdateInterval = iniFile.getIntValue();
1296 else if (iniFile.isName("icyMetaInterval"))
1297 chanMgr->icyMetaInterval = iniFile.getIntValue();
1298 else if (iniFile.isName("maxServIn"))
1299 servMgr->maxServIn = iniFile.getIntValue();
1300 else if (iniFile.isName("chanLog"))
1301 servMgr->chanLog.set(iniFile.getStrValue(),String::T_ASCII);
1303 else if (iniFile.isName("rootMsg"))
1304 rootMsg.set(iniFile.getStrValue());
1305 else if (iniFile.isName("networkID"))
1306 networkID.fromStr(iniFile.getStrValue());
1307 else if (iniFile.isName("authType"))
1309 char *t = iniFile.getStrValue();
1310 if (stricmp(t,"cookie")==0)
1311 servMgr->authType = ServMgr::AUTH_COOKIE;
1312 else if (stricmp(t,"http-basic")==0)
1313 servMgr->authType = ServMgr::AUTH_HTTPBASIC;
1314 }else if (iniFile.isName("cookiesExpire"))
1316 char *t = iniFile.getStrValue();
1317 if (stricmp(t,"never")==0)
1318 servMgr->cookieList.neverExpire = true;
1319 else if (stricmp(t,"session")==0)
1320 servMgr->cookieList.neverExpire = false;
1326 else if (iniFile.isName("password"))
1327 strcpy(servMgr->password,iniFile.getStrValue());
1328 else if (iniFile.isName("maxUptime"))
1329 chanMgr->maxUptime = iniFile.getIntValue();
1333 else if (iniFile.isName("rootHost"))
1336 servMgr->rootHost = iniFile.getStrValue();
1338 }else if (iniFile.isName("deadHitAge"))
1339 chanMgr->deadHitAge = iniFile.getIntValue();
1340 else if (iniFile.isName("tryoutDelay"))
1341 servMgr->tryoutDelay = iniFile.getIntValue();
1342 else if (iniFile.isName("refreshHTML"))
1343 refreshHTML = iniFile.getIntValue();
1344 else if (iniFile.isName("relayBroadcast"))
1346 servMgr->relayBroadcast = iniFile.getIntValue();
1347 if (servMgr->relayBroadcast < 30)
1348 servMgr->relayBroadcast = 30;
1350 else if (iniFile.isName("minBroadcastTTL"))
1351 chanMgr->minBroadcastTTL = iniFile.getIntValue();
1352 else if (iniFile.isName("maxBroadcastTTL"))
1353 chanMgr->maxBroadcastTTL = iniFile.getIntValue();
1354 else if (iniFile.isName("pushTimeout"))
1355 chanMgr->pushTimeout = iniFile.getIntValue();
1356 else if (iniFile.isName("pushTries"))
1357 chanMgr->pushTries = iniFile.getIntValue();
1358 else if (iniFile.isName("maxPushHops"))
1359 chanMgr->maxPushHops = iniFile.getIntValue();
1360 else if (iniFile.isName("autoQuery"))
1362 chanMgr->autoQuery = iniFile.getIntValue();
1363 if ((chanMgr->autoQuery < 300) && (chanMgr->autoQuery > 0))
1364 chanMgr->autoQuery = 300;
1366 else if (iniFile.isName("queryTTL"))
1368 servMgr->queryTTL = iniFile.getIntValue();
1372 else if (iniFile.isName("autoRelayKeep"))
1373 servMgr->autoRelayKeep = iniFile.getIntValue();
1374 else if (iniFile.isName("autoMaxRelaySetting"))
1375 servMgr->autoMaxRelaySetting = iniFile.getIntValue();
1376 else if (iniFile.isName("autoBumpSkipCount"))
1377 servMgr->autoBumpSkipCount = iniFile.getIntValue();
1378 else if (iniFile.isName("kickPushStartRelays"))
1379 servMgr->kickPushStartRelays = iniFile.getIntValue();
1380 else if (iniFile.isName("kickPushInterval"))
1382 servMgr->kickPushInterval = iniFile.getIntValue();
1383 if (servMgr->kickPushInterval < 60)
1384 servMgr->kickPushInterval = 0;
1386 else if (iniFile.isName("allowConnectPCST"))
1387 servMgr->allowConnectPCST = iniFile.getIntValue();
1388 else if (iniFile.isName("enableGetName"))
1389 servMgr->enableGetName = iniFile.getIntValue();
1391 else if (iniFile.isName("maxRelaysIndexTxt")) // for PCRaw (relay)
1392 servMgr->maxRelaysIndexTxt = iniFile.getIntValue();
1395 else if (iniFile.isName("getModulePath"))
1396 servMgr->getModulePath = iniFile.getBoolValue();
1397 else if (iniFile.isName("clearPLS"))
1398 servMgr->clearPLS = iniFile.getBoolValue();
1399 else if (iniFile.isName("writeLogFile"))
1400 servMgr->writeLogFile = iniFile.getBoolValue();
1403 else if (iniFile.isName("rootHost2"))
1406 servMgr->rootHost2 = iniFile.getStrValue();
1408 else if (iniFile.isName("autoPort0Kick"))
1409 servMgr->autoPort0Kick = iniFile.getBoolValue();
1410 else if (iniFile.isName("allowOnlyVP"))
1411 servMgr->allowOnlyVP = iniFile.getBoolValue();
1412 else if (iniFile.isName("kickKeepTime"))
1413 servMgr->kickKeepTime = iniFile.getIntValue();
1414 else if (iniFile.isName("vpDebug"))
1415 servMgr->vpDebug = iniFile.getBoolValue();
1416 else if (iniFile.isName("saveIniChannel"))
1417 servMgr->saveIniChannel = iniFile.getBoolValue();
1419 else if (iniFile.isName("saveGuiPos"))
1420 servMgr->saveGuiPos = iniFile.getBoolValue();
1421 else if (iniFile.isName("guiTop"))
1422 winPlace.rcNormalPosition.top = iniFile.getIntValue();
1423 else if (iniFile.isName("guiBottom"))
1424 winPlace.rcNormalPosition.bottom = iniFile.getIntValue();
1425 else if (iniFile.isName("guiLeft"))
1426 winPlace.rcNormalPosition.left = iniFile.getIntValue();
1427 else if (iniFile.isName("guiRight")){
1428 winPlace.rcNormalPosition.right = iniFile.getIntValue();
1429 winPlace.length = sizeof(winPlace);
1431 winPlace.showCmd = 1;
1432 winPlace.ptMinPosition.x = -1;
1433 winPlace.ptMinPosition.y = -1;
1434 winPlace.ptMaxPosition.x = -1;
1435 winPlace.ptMaxPosition.y = -1;
1436 if (servMgr->saveGuiPos){
1441 else if (iniFile.isName("topmostGui"))
1443 servMgr->topmostGui = iniFile.getBoolValue();
1444 } else if (iniFile.isName("startWithGui"))
1446 servMgr->startWithGui = iniFile.getBoolValue();
1451 else if (iniFile.isName("logDebug"))
1452 showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_DEBUG:0;
1453 else if (iniFile.isName("logErrors"))
1454 showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_ERROR:0;
1455 else if (iniFile.isName("logNetwork"))
1456 showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_NETWORK:0;
1457 else if (iniFile.isName("logChannel"))
1458 showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_CHANNEL:0;
1459 else if (iniFile.isName("pauseLog"))
1460 pauseLog = iniFile.getBoolValue();
1461 else if (iniFile.isName("idleSleepTime"))
1462 sys->idleSleepTime = iniFile.getIntValue();
1463 else if (iniFile.isName("[Server1]"))
1464 allowServer1 = readServerSettings(iniFile,allowServer1);
1465 else if (iniFile.isName("[Server2]"))
1466 allowServer2 = readServerSettings(iniFile,allowServer2);
1467 else if (iniFile.isName("[Filter]"))
1469 readFilterSettings(iniFile,filters[numFilters]);
1471 if (numFilters < (MAX_FILTERS-1))
1474 else if (iniFile.isName("[Notify]"))
1476 notifyMask = NT_UPGRADE;
1477 while (iniFile.readNext())
1479 if (iniFile.isName("[End]"))
1481 else if (iniFile.isName("PeerCast"))
1482 notifyMask |= iniFile.getBoolValue()?NT_PEERCAST:0;
1483 else if (iniFile.isName("Broadcasters"))
1484 notifyMask |= iniFile.getBoolValue()?NT_BROADCASTERS:0;
1485 else if (iniFile.isName("TrackInfo"))
1486 notifyMask |= iniFile.getBoolValue()?NT_TRACKINFO:0;
1490 else if (iniFile.isName("[RelayChannel]"))
1493 bool stayConnected=false;
1495 while (iniFile.readNext())
1497 if (iniFile.isName("[End]"))
1499 else if (iniFile.isName("name"))
1500 info.name.set(iniFile.getStrValue());
1501 else if (iniFile.isName("id"))
1502 info.id.fromStr(iniFile.getStrValue());
1503 else if (iniFile.isName("sourceType"))
1504 info.srcProtocol = ChanInfo::getProtocolFromStr(iniFile.getStrValue());
1505 else if (iniFile.isName("contentType"))
1506 info.contentType = ChanInfo::getTypeFromStr(iniFile.getStrValue());
1507 else if (iniFile.isName("stayConnected"))
1508 stayConnected = iniFile.getBoolValue();
1509 else if (iniFile.isName("sourceURL"))
1510 sourceURL.set(iniFile.getStrValue());
1511 else if (iniFile.isName("genre"))
1512 info.genre.set(iniFile.getStrValue());
1513 else if (iniFile.isName("contactURL"))
1514 info.url.set(iniFile.getStrValue());
1515 else if (iniFile.isName("bitrate"))
1516 info.bitrate = atoi(iniFile.getStrValue());
1517 else if (iniFile.isName("tracker"))
1522 hit.host.fromStrName(iniFile.getStrValue(),DEFAULT_PORT);
1523 hit.rhost[0] = hit.host;
1524 hit.rhost[1] = hit.host;
1525 hit.chanID = info.id;
1527 chanMgr->addHit(hit);
1531 if (sourceURL.isEmpty())
1533 chanMgr->createRelay(info,stayConnected);
1536 info.bcID = chanMgr->broadcastID;
1537 Channel *c = chanMgr->createChannel(info,NULL);
1539 c->startURL(sourceURL.cstr());
1541 } else if (iniFile.isName("[Host]"))
1544 ServHost::TYPE type=ServHost::T_NONE;
1545 bool firewalled=false;
1546 unsigned int time=0;
1547 while (iniFile.readNext())
1549 if (iniFile.isName("[End]"))
1551 else if (iniFile.isName("address"))
1552 h.fromStrIP(iniFile.getStrValue(),DEFAULT_PORT);
1553 else if (iniFile.isName("type"))
1554 type = ServHost::getTypeFromStr(iniFile.getStrValue());
1555 else if (iniFile.isName("time"))
1556 time = iniFile.getIntValue();
1558 servMgr->addHost(h,type,time);
1560 } else if (iniFile.isName("[ValidBCID]"))
1562 BCID *bcid = new BCID();
1563 while (iniFile.readNext())
1565 if (iniFile.isName("[End]"))
1567 else if (iniFile.isName("id"))
1568 bcid->id.fromStr(iniFile.getStrValue());
1569 else if (iniFile.isName("name"))
1570 bcid->name.set(iniFile.getStrValue());
1571 else if (iniFile.isName("email"))
1572 bcid->email.set(iniFile.getStrValue());
1573 else if (iniFile.isName("url"))
1574 bcid->url.set(iniFile.getStrValue());
1575 else if (iniFile.isName("valid"))
1576 bcid->valid = iniFile.getBoolValue();
1578 servMgr->addValidBCID(bcid);
1584 setFilterDefaults();
1588 // --------------------------------------------------
1589 unsigned int ServMgr::numStreams(GnuID &cid, Servent::TYPE tp, bool all)
1592 Servent *sv = servents;
1595 if (sv->isConnected())
1597 if (sv->chanID.isSame(cid))
1598 if (all || !sv->isPrivate())
1604 // --------------------------------------------------
1605 unsigned int ServMgr::numStreams(Servent::TYPE tp, bool all)
1608 Servent *sv = servents;
1611 if (sv->isConnected())
1613 if (all || !sv->isPrivate())
1615 // for PCRaw (relay) start.
1616 if(tp == Servent::T_RELAY)
1618 Channel *ch = chanMgr->findChannelByID(sv->chanID);
1620 // index.txt
\82Í
\83J
\83E
\83\93\83g
\82µ
\82È
\82¢
1625 // for PCRaw (relay) end.
1635 // --------------------------------------------------
1636 bool ServMgr::getChannel(char *str,ChanInfo &info, bool relay)
1638 // remove file extension (only added for winamp)
1639 //char *ext = strstr(str,".");
1640 //if (ext) *ext = 0;
1642 procConnectArgs(str,info);
1644 WLockBlock wb(&(chanMgr->channellock));
1649 ch = chanMgr->findChannelByNameID(info);
1650 if (ch && ch->thread.active)
1653 if (!ch->isPlaying())
1657 ch->info.lastPlayStart = 0; // force reconnect
1658 ch->info.lastPlayEnd = 0;
1663 info = ch->info; // get updated channel info
1671 ch = chanMgr->findAndRelay(info);
1674 //
\81«Exception point
1675 info = ch->info; //get updated channel info
1683 // --------------------------------------------------
1684 int ServMgr::findChannel(ChanInfo &info)
1688 info.id.toStr(idStr);
1691 if (info.id.isSet())
1693 // if we have an ID then try and connect to known hosts carrying channel.
1694 ServHost sh = getOutgoingServent(info.id);
1695 addOutgoing(sh.host,info.id,true);
1701 XML::Node *n = info.createQueryXML();
1703 pack.initFind(NULL,&xml,servMgr->queryTTL);
1705 addReplyID(pack.id);
1706 int cnt = broadcast(pack,NULL);
1708 LOG_NETWORK("Querying network: %s %s - %d servents",info.name.cstr(),idStr,cnt);
1714 // --------------------------------------------------
1715 // add outgoing network connection from string (ip:port format)
1716 bool ServMgr::addOutgoing(Host h, GnuID &netid, bool pri)
1721 if (!findServent(h.ip,h.port,netid))
1723 Servent *sv = allocServent();
1727 sv->priorityConnect = true;
1728 sv->networkID = netid;
1729 sv->initOutgoing(h,Servent::T_OUTGOING);
1737 // --------------------------------------------------
1738 Servent *ServMgr::findConnection(Servent::TYPE t,GnuID &sid)
1740 Servent *sv = servents;
1743 if (sv->isConnected())
1745 if (sv->remoteID.isSame(sid))
1752 // --------------------------------------------------
1753 void ServMgr::procConnectArgs(char *str,ChanInfo &info)
1755 char arg[MAX_CGI_LEN];
1756 char curr[MAX_CGI_LEN];
1758 char *args = strstr(str,"?");
1762 info.initNameID(str);
1767 while (args=nextCGIarg(args,curr,arg))
1769 LOG_DEBUG("cmd: %s, arg: %s",curr,arg);
1771 if (strcmp(curr,"sip")==0)
1772 // sip - add network connection to client with channel
1775 h.fromStrName(arg,DEFAULT_PORT);
1776 if (addOutgoing(h,servMgr->networkID,true))
1777 LOG_NETWORK("Added connection: %s",arg);
1779 }else if (strcmp(curr,"pip")==0)
1780 // pip - add private network connection to client with channel
1783 h.fromStrName(arg,DEFAULT_PORT);
1784 if (addOutgoing(h,info.id,true))
1785 LOG_NETWORK("Added private connection: %s",arg);
1786 }else if (strcmp(curr,"ip")==0)
1790 h.fromStrName(arg,DEFAULT_PORT);
1795 hit.rhost[1].init();
1796 hit.chanID = info.id;
1799 chanMgr->addHit(hit);
1800 }else if (strcmp(curr,"tip")==0)
1801 // tip - add tracker hit
1804 h.fromStrName(arg,DEFAULT_PORT);
1805 chanMgr->hitlistlock.on();
1806 chanMgr->addHit(h,info.id,true);
1807 chanMgr->hitlistlock.off();
1816 // --------------------------------------------------
1817 bool ServMgr::start()
1823 #if PRIVATE_BROADCASTER
1829 LOG_DEBUG("Peercast %s, %s %s",PCX_VERSTRING_EX,peercastApp->getClientTypeOS(),priv);
1831 LOG_DEBUG("Peercast %s, %s %s",PCX_VERSTRING,peercastApp->getClientTypeOS(),priv);
1834 sessionID.toStr(idStr);
1835 LOG_DEBUG("SessionID: %s",idStr);
1837 chanMgr->broadcastID.toStr(idStr);
1838 LOG_DEBUG("BroadcastID: %s",idStr);
1842 serverThread.func = ServMgr::serverProc;
1843 if (!sys->startThread(&serverThread))
1846 idleThread.func = ServMgr::idleProc;
1847 if (!sys->startThread(&idleThread))
1852 // --------------------------------------------------
1853 int ServMgr::clientProc(ThreadInfo *thread)
1859 netID = servMgr->networkID;
1861 while(thread->active)
1863 if (servMgr->autoConnect)
1865 if (servMgr->needConnections() || servMgr->forceLookup)
1867 if (servMgr->needHosts() || servMgr->forceLookup)
1869 // do lookup to find some hosts
1872 lh.fromStrName(servMgr->connectHost,DEFAULT_PORT);
1875 if (!servMgr->findServent(lh.ip,lh.port,netID))
1877 Servent *sv = servMgr->allocServent();
1880 LOG_DEBUG("Lookup: %s",servMgr->connectHost);
1881 sv->networkID = netID;
1882 sv->initOutgoing(lh,Servent::T_LOOKUP);
1883 servMgr->forceLookup = false;
1888 for(int i=0; i<MAX_TRYOUT; i++)
1890 if (servMgr->outUsedFull())
1892 if (servMgr->tryFull())
1896 ServHost sh = servMgr->getOutgoingServent(netID);
1898 if (!servMgr->addOutgoing(sh.host,netID,false))
1899 servMgr->deadHost(sh.host,ServHost::T_SERVENT);
1900 sys->sleep(servMgr->tryoutDelay);
1906 Servent *s = servMgr->servents;
1910 if (s->type == Servent::T_OUTGOING)
1911 s->thread.active = false;
1922 // -----------------------------------
1923 bool ServMgr::acceptGIV(ClientSocket *sock)
1925 Servent *sv = servents;
1928 if (sv->type == Servent::T_COUT)
1930 if (sv->acceptGIV(sock))
1938 // -----------------------------------
1939 int ServMgr::broadcastPushRequest(ChanHit &hit, Host &to, GnuID &chanID, Servent::TYPE type)
1942 MemoryStream pmem(pack.data,sizeof(pack.data));
1943 AtomStream atom(pmem);
1946 atom.writeParent(PCP_BCST,8);
1948 atom.writeParent(PCP_BCST,10);
1950 atom.writeChar(PCP_BCST_GROUP,PCP_BCST_GROUP_ALL);
1951 atom.writeChar(PCP_BCST_HOPS,0);
1952 atom.writeChar(PCP_BCST_TTL,7);
1953 atom.writeBytes(PCP_BCST_DEST,hit.sessionID.id,16);
1954 atom.writeBytes(PCP_BCST_FROM,servMgr->sessionID.id,16);
1955 atom.writeInt(PCP_BCST_VERSION,PCP_CLIENT_VERSION);
1956 atom.writeInt(PCP_BCST_VERSION_VP,PCP_CLIENT_VERSION_VP);
1958 atom.writeBytes(PCP_BCST_VERSION_EX_PREFIX,PCP_CLIENT_VERSION_EX_PREFIX,2);
1959 atom.writeShort(PCP_BCST_VERSION_EX_NUMBER,PCP_CLIENT_VERSION_EX_NUMBER);
1961 atom.writeParent(PCP_PUSH,3);
1962 atom.writeInt(PCP_PUSH_IP,to.ip);
1963 atom.writeShort(PCP_PUSH_PORT,to.port);
1964 atom.writeBytes(PCP_PUSH_CHANID,chanID.id,16);
1967 pack.len = pmem.pos;
1968 pack.type = ChanPacket::T_PCP;
1974 return servMgr->broadcastPacket(pack,noID,servMgr->sessionID,hit.sessionID,type);
1977 // --------------------------------------------------
1978 void ServMgr::writeRootAtoms(AtomStream &atom, bool getUpdate)
1980 atom.writeParent(PCP_ROOT,5 + (getUpdate?1:0));
1981 atom.writeInt(PCP_ROOT_UPDINT,chanMgr->hostUpdateInterval);
1982 atom.writeString(PCP_ROOT_URL,"download.php");
1983 atom.writeInt(PCP_ROOT_CHECKVER,PCP_ROOT_VERSION);
1984 atom.writeInt(PCP_ROOT_NEXT,chanMgr->hostUpdateInterval);
1985 atom.writeString(PCP_MESG_ASCII,rootMsg.cstr());
1987 atom.writeParent(PCP_ROOT_UPDATE,0);
1990 // --------------------------------------------------
1991 void ServMgr::broadcastRootSettings(bool getUpdate)
1997 MemoryStream mem(pack.data,sizeof(pack.data));
1998 AtomStream atom(mem);
2000 atom.writeParent(PCP_BCST,7);
2002 atom.writeParent(PCP_BCST,9);
2004 atom.writeChar(PCP_BCST_GROUP,PCP_BCST_GROUP_TRACKERS);
2005 atom.writeChar(PCP_BCST_HOPS,0);
2006 atom.writeChar(PCP_BCST_TTL,7);
2007 atom.writeBytes(PCP_BCST_FROM,sessionID.id,16);
2008 atom.writeInt(PCP_BCST_VERSION,PCP_CLIENT_VERSION);
2009 atom.writeInt(PCP_BCST_VERSION_VP,PCP_CLIENT_VERSION_VP);
2011 atom.writeBytes(PCP_BCST_VERSION_EX_PREFIX,PCP_CLIENT_VERSION_EX_PREFIX,2);
2012 atom.writeShort(PCP_BCST_VERSION_EX_NUMBER,PCP_CLIENT_VERSION_EX_NUMBER);
2014 writeRootAtoms(atom,getUpdate);
2023 broadcastPacket(pack,noID,servMgr->sessionID,noID,Servent::T_CIN);
2026 // --------------------------------------------------
2027 int ServMgr::broadcastPacket(ChanPacket &pack,GnuID &chanID,GnuID &srcID, GnuID &destID, Servent::TYPE type)
2031 Servent *sv = servents;
2034 if (sv->sendPacket(pack,chanID,srcID,destID,type))
2041 // --------------------------------------------------
2042 int ServMgr::idleProc(ThreadInfo *thread)
2047 unsigned int lastPasvFind=0;
2048 unsigned int lastBroadcast=0;
2051 // nothing much to do for the first couple of seconds, so just hang around.
2054 unsigned int lastBWcheck=0;
2055 unsigned int bytesIn=0,bytesOut=0;
2057 unsigned int lastBroadcastConnect = 0;
2058 unsigned int lastRootBroadcast = 0;
2060 unsigned int lastForceIPCheck = 0;
2062 while(thread->active)
2068 unsigned int ctime = sys->getTime();
2071 if (!servMgr->forceIP.isEmpty())
2073 if ((ctime-lastForceIPCheck) > 60)
2075 if (servMgr->checkForceIP())
2079 chanMgr->broadcastTrackerUpdate(noID,true);
2081 lastForceIPCheck = ctime;
2086 if (chanMgr->isBroadcasting())
2088 if ((ctime-lastBroadcastConnect) > 30)
2090 servMgr->connectBroadcaster();
2091 lastBroadcastConnect = ctime;
2095 if (servMgr->isRoot)
2097 if ((servMgr->lastIncoming) && ((ctime-servMgr->lastIncoming) > 60*60))
2099 peercastInst->saveSettings();
2103 if ((ctime-lastRootBroadcast) > chanMgr->hostUpdateInterval)
2105 servMgr->broadcastRootSettings(true);
2106 lastRootBroadcast = ctime;
2112 chanMgr->clearDeadHits(true);
2114 if (servMgr->kickPushStartRelays && servMgr->kickPushInterval) //JP-EX
2116 servMgr->banFirewalledHost();
2119 if (servMgr->shutdownTimer)
2121 if (--servMgr->shutdownTimer <= 0)
2123 peercastInst->saveSettings();
2128 // shutdown idle channels
2129 if (chanMgr->numIdleChannels() > ChanMgr::MAX_IDLE_CHANNELS)
2130 chanMgr->closeOldestIdle();
2136 sys->endThread(thread);
2137 // thread->unlock();
2141 // --------------------------------------------------
2142 int ServMgr::serverProc(ThreadInfo *thread)
2147 Servent *serv = servMgr->allocServent();
2148 Servent *serv2 = servMgr->allocServent();
2150 unsigned int lastLookupTime=0;
2153 while (thread->active)
2156 if (servMgr->restartServer)
2158 serv->abort(); // force close
2159 serv2->abort(); // force close
2162 servMgr->restartServer = false;
2165 if (servMgr->autoServe)
2167 serv->allow = servMgr->allowServer1;
2168 serv2->allow = servMgr->allowServer2;
2171 if ((!serv->sock) || (!serv2->sock))
2173 LOG_DEBUG("Starting servers");
2174 // servMgr->forceLookup = true;
2176 //if (servMgr->serverHost.ip != 0)
2179 if (servMgr->forceNormal)
2180 servMgr->setFirewall(ServMgr::FW_OFF);
2182 servMgr->setFirewall(ServMgr::FW_UNKNOWN);
2184 Host h = servMgr->serverHost;
2187 serv->initServer(h);
2191 serv2->initServer(h);
2198 serv->abort(); // force close
2199 serv2->abort(); // force close
2201 // cancel incoming connectuions
2202 Servent *s = servMgr->servents;
2205 if (s->type == Servent::T_INCOMING)
2206 s->thread.active = false;
2210 servMgr->setFirewall(ServMgr::FW_ON);
2217 sys->endThread(thread);
2218 // thread->unlock();
2222 // -----------------------------------
2223 void ServMgr::setMaxRelays(int max)
2225 if (max < MIN_RELAYS)
2230 // -----------------------------------
2231 XML::Node *ServMgr::createServentXML()
2234 return new XML::Node("servent agent=\"%s\" ",PCX_AGENT);
2237 // --------------------------------------------------
2238 const char *ServHost::getTypeStr(TYPE t)
2242 case T_NONE: return "NONE";
2243 case T_STREAM: return "STREAM";
2244 case T_CHANNEL: return "CHANNEL";
2245 case T_SERVENT: return "SERVENT";
2246 case T_TRACKER: return "TRACKER";
2250 // --------------------------------------------------
2251 ServHost::TYPE ServHost::getTypeFromStr(const char *s)
2253 if (stricmp(s,"NONE")==0)
2255 else if (stricmp(s,"SERVENT")==0)
2257 else if (stricmp(s,"STREAM")==0)
2259 else if (stricmp(s,"CHANNEL")==0)
2261 else if (stricmp(s,"TRACKER")==0)
2268 // --------------------------------------------------
2269 bool ServFilter::writeVariable(Stream &out, const String &var)
2273 if (var == "network")
2274 strcpy(buf,(flags & F_NETWORK)?"1":"0");
2275 else if (var == "private")
2276 strcpy(buf,(flags & F_PRIVATE)?"1":"0");
2277 else if (var == "direct")
2278 strcpy(buf,(flags & F_DIRECT)?"1":"0");
2279 else if (var == "banned")
2280 strcpy(buf,(flags & F_BAN)?"1":"0");
2281 else if (var == "ip")
2287 out.writeString(buf);
2290 // --------------------------------------------------
2291 bool BCID::writeVariable(Stream &out, const String &var)
2297 else if (var == "name")
2298 strcpy(buf,name.cstr());
2299 else if (var == "email")
2300 strcpy(buf,email.cstr());
2301 else if (var == "url")
2302 strcpy(buf,url.cstr());
2303 else if (var == "valid")
2304 strcpy(buf,valid?"Yes":"No");
2309 out.writeString(buf);
2314 // --------------------------------------------------
2315 bool ServMgr::writeVariable(Stream &out, const String &var)
2320 if (var == "version")
2322 strcpy(buf,PCX_VERSTRING_EX);
2324 strcpy(buf,PCX_VERSTRING);
2326 else if (var == "uptime")
2328 str.setFromStopwatch(getUptime());
2329 str.convertTo(String::T_HTML);
2330 strcpy(buf,str.cstr());
2331 }else if (var == "numRelays")
2332 sprintf(buf,"%d",numStreams(Servent::T_RELAY,true));
2333 else if (var == "numDirect")
2334 sprintf(buf,"%d",numStreams(Servent::T_DIRECT,true));
2335 else if (var == "totalConnected")
2336 sprintf(buf,"%d",totalConnected());
2337 else if (var == "numServHosts")
2338 sprintf(buf,"%d",numHosts(ServHost::T_SERVENT));
2339 else if (var == "numServents")
2340 sprintf(buf,"%d",numServents());
2341 else if (var == "serverPort")
2342 sprintf(buf,"%d",serverHost.port);
2343 else if (var == "serverIP")
2344 serverHost.IPtoStr(buf);
2345 else if (var == "ypAddress")
2346 strcpy(buf,rootHost.cstr());
2347 else if (var == "password")
2348 strcpy(buf,password);
2349 else if (var == "isFirewalled")
2350 sprintf(buf,"%d",getFirewall()==FW_ON?1:0);
2351 else if (var == "firewallKnown")
2352 sprintf(buf,"%d",getFirewall()==FW_UNKNOWN?0:1);
2353 else if (var == "rootMsg")
2354 strcpy(buf,rootMsg);
2355 else if (var == "isRoot")
2356 sprintf(buf,"%d",isRoot?1:0);
2357 else if (var == "isPrivate")
2358 sprintf(buf,"%d",(PCP_BROADCAST_FLAGS&1)?1:0);
2359 else if (var == "forceYP")
2360 sprintf(buf,"%d",PCP_FORCE_YP?1:0);
2361 else if (var == "refreshHTML")
2362 sprintf(buf,"%d",refreshHTML?refreshHTML:0x0fffffff);
2363 else if (var == "maxRelays")
2364 sprintf(buf,"%d",maxRelays);
2365 else if (var == "maxDirect")
2366 sprintf(buf,"%d",maxDirect);
2367 else if (var == "maxBitrateOut")
2368 sprintf(buf,"%d",maxBitrateOut);
2369 else if (var == "maxControlsIn")
2370 sprintf(buf,"%d",maxControl);
2371 else if (var == "maxServIn")
2372 sprintf(buf,"%d",maxServIn);
2373 else if (var == "numFilters")
2374 sprintf(buf,"%d",numFilters+1);
2375 else if (var == "maxPGNUIn")
2376 sprintf(buf,"%d",maxGnuIncoming);
2377 else if (var == "minPGNUIn")
2378 sprintf(buf,"%d",minGnuIncoming);
2379 else if (var == "numActive1")
2380 sprintf(buf,"%d",numActiveOnPort(serverHost.port));
2381 else if (var == "numActive2")
2382 sprintf(buf,"%d",numActiveOnPort(serverHost.port+1));
2383 else if (var == "numPGNU")
2384 sprintf(buf,"%d",numConnected(Servent::T_PGNU));
2385 else if (var == "numCIN")
2386 sprintf(buf,"%d",numConnected(Servent::T_CIN));
2387 else if (var == "numCOUT")
2388 sprintf(buf,"%d",numConnected(Servent::T_COUT));
2389 else if (var == "numIncoming")
2390 sprintf(buf,"%d",numActive(Servent::T_INCOMING));
2391 else if (var == "numValidBCID")
2394 BCID *bcid = validBCID;
2400 sprintf(buf,"%d",cnt);
2403 else if (var == "disabled")
2404 sprintf(buf,"%d",isDisabled);
2407 else if (var.startsWith("autoRelayKeep")) {
2408 if (var == "autoRelayKeep.0")
2409 strcpy(buf, (autoRelayKeep == 0) ? "1":"0");
2410 else if (var == "autoRelayKeep.1")
2411 strcpy(buf, (autoRelayKeep == 1) ? "1":"0");
2412 else if (var == "autoRelayKeep.2")
2413 strcpy(buf, (autoRelayKeep == 2) ? "1":"0");
2414 } else if (var == "autoMaxRelaySetting")
2415 sprintf(buf,"%d",autoMaxRelaySetting);
2416 else if (var == "autoBumpSkipCount")
2417 sprintf(buf,"%d",autoBumpSkipCount);
2418 else if (var == "kickPushStartRelays")
2419 sprintf(buf,"%d",kickPushStartRelays);
2420 else if (var == "kickPushInterval")
2421 sprintf(buf,"%d",kickPushInterval);
2422 else if (var == "allowConnectPCST")
2423 strcpy(buf, (allowConnectPCST == 1) ? "1":"0");
2424 else if (var == "enableGetName")
2425 strcpy(buf, (enableGetName == 1)? "1":"0");
2428 else if (var == "ypAddress2")
2429 strcpy(buf,rootHost2.cstr());
2430 else if (var.startsWith("autoPort0Kick")) {
2431 if (var == "autoPort0Kick.0")
2432 strcpy(buf, (autoPort0Kick == 0) ? "1":"0");
2433 else if (var == "autoPort0Kick.1")
2434 strcpy(buf, (autoPort0Kick == 1) ? "1":"0");
2436 else if (var.startsWith("allowOnlyVP")) {
2437 if (var == "allowOnlyVP.0")
2438 strcpy(buf, (allowOnlyVP == 0) ? "1":"0");
2439 else if (var == "allowOnlyVP.1")
2440 strcpy(buf, (allowOnlyVP == 1) ? "1":"0");
2442 else if (var == "kickKeepTime")
2443 sprintf(buf, "%d",kickKeepTime);
2445 else if (var == "serverPort1")
2446 sprintf(buf,"%d",serverHost.port);
2447 else if (var == "serverLocalIP")
2449 Host lh(ClientSocket::getIP(NULL),0);
2453 }else if (var == "upgradeURL")
2454 strcpy(buf,servMgr->downloadURL);
2455 else if (var == "serverPort2")
2456 sprintf(buf,"%d",serverHost.port+1);
2457 else if (var.startsWith("allow."))
2459 if (var == "allow.HTML1")
2460 strcpy(buf,(allowServer1&Servent::ALLOW_HTML)?"1":"0");
2461 else if (var == "allow.HTML2")
2462 strcpy(buf,(allowServer2&Servent::ALLOW_HTML)?"1":"0");
2463 else if (var == "allow.broadcasting1")
2464 strcpy(buf,(allowServer1&Servent::ALLOW_BROADCAST)?"1":"0");
2465 else if (var == "allow.broadcasting2")
2466 strcpy(buf,(allowServer2&Servent::ALLOW_BROADCAST)?"1":"0");
2467 else if (var == "allow.network1")
2468 strcpy(buf,(allowServer1&Servent::ALLOW_NETWORK)?"1":"0");
2469 else if (var == "allow.direct1")
2470 strcpy(buf,(allowServer1&Servent::ALLOW_DIRECT)?"1":"0");
2471 }else if (var.startsWith("auth."))
2473 if (var == "auth.useCookies")
2474 strcpy(buf,(authType==AUTH_COOKIE)?"1":"0");
2475 else if (var == "auth.useHTTP")
2476 strcpy(buf,(authType==AUTH_HTTPBASIC)?"1":"0");
2477 else if (var == "auth.useSessionCookies")
2478 strcpy(buf,(cookieList.neverExpire==false)?"1":"0");
2480 }else if (var.startsWith("log."))
2482 if (var == "log.debug")
2483 strcpy(buf,(showLog&(1<<LogBuffer::T_DEBUG))?"1":"0");
2484 else if (var == "log.errors")
2485 strcpy(buf,(showLog&(1<<LogBuffer::T_ERROR))?"1":"0");
2486 else if (var == "log.gnet")
2487 strcpy(buf,(showLog&(1<<LogBuffer::T_NETWORK))?"1":"0");
2488 else if (var == "log.channel")
2489 strcpy(buf,(showLog&(1<<LogBuffer::T_CHANNEL))?"1":"0");
2492 }else if (var == "test")
2494 out.writeUTF8(0x304b);
2495 out.writeUTF8(0x304d);
2496 out.writeUTF8(0x304f);
2497 out.writeUTF8(0x3051);
2498 out.writeUTF8(0x3053);
2500 out.writeUTF8(0x0041);
2501 out.writeUTF8(0x0042);
2502 out.writeUTF8(0x0043);
2503 out.writeUTF8(0x0044);
2511 }else if (var == "maxRelaysIndexTxt") // for PCRaw (relay)
2512 sprintf(buf, "%d", maxRelaysIndexTxt);
2516 out.writeString(buf);
2519 // --------------------------------------------------
2521 bool ServMgr::isCheckPushStream()
2523 if (servMgr->kickPushStartRelays)
2524 if (servMgr->numStreams(Servent::T_RELAY,false)>=(servMgr->kickPushStartRelays-1))
2529 // --------------------------------------------------
2531 void ServMgr::banFirewalledHost()
2533 unsigned int kickpushtime = sys->getTime();
2534 if ((kickpushtime-servMgr->kickPushTime) > servMgr->kickPushInterval)
2536 servMgr->kickPushTime = kickpushtime;
2537 Servent *s = servMgr->servents;
2538 LOG_DEBUG("Servent scan start.");
2541 if (s->type != Servent::T_NONE)
2543 Host h = s->getHost();
2547 unsigned int tnum = 0;
2550 tnum = sys->getTime() - s->lastConnect;
2551 if ((s->type==Servent::T_RELAY) && (s->status==Servent::S_CONNECTED) && (tnum>servMgr->kickPushInterval))
2553 /* ChanHitList *hits[ChanMgr::MAX_HITLISTS];
2555 for(int i=0; i<ChanMgr::MAX_HITLISTS; i++)
2557 ChanHitList *chl = &chanMgr->hitlists[i];
2559 hits[numHits++] = chl;
2566 for(int k=0; k<numHits; k++)
2568 ChanHitList *chl = hits[k];
2571 for (int j=0; j<ChanHitList::MAX_HITS; j++ )
2573 ChanHit *hit = &chl->hits[j];
2574 if (hit->host.isValid() && (h2.ip == hit->host.ip))
2576 if (hit->firewalled)
2578 numRelay = hit->numRelays;
2584 if ((isfw==true) && (numRelay==0))
2588 if (servMgr->isCheckPushStream())
2590 s->thread.active = false;
2591 LOG_ERROR("Stop firewalled Servent : %s",hostName);
2595 chanMgr->hitlistlock.on();
2596 ChanHitList *chl = chanMgr->findHitListByID(s->chanID);
2598 ChanHit *hit = chl->hit;
2600 if ((hit->numHops == 1) && hit->host.isValid() && (h2.ip == hit->host.ip) && hit->firewalled /*&& !hit->numRelays*/)
2604 if (servMgr->isCheckPushStream())
2606 s->thread.active = false;
2607 LOG_ERROR("Stop firewalled Servent : %s",hostName);
2614 chanMgr->hitlistlock.off();
2621 LOG_DEBUG("Servent scan finished.");
2625 // --------------------------------------------------
2627 static ChanHit *findServentHit(Servent *s)
2629 ChanHitList *chl = chanMgr->findHitListByID(s->chanID);
2630 Host h = s->getHost();
2634 ChanHit *hit = chl->hit;
2637 if ((hit->numHops == 1) && hit->host.isValid() && (h.ip == hit->host.ip))
2645 // --------------------------------------------------
2646 int ServMgr::kickUnrelayableHost(GnuID &chid, ChanHit &sendhit)
2649 Servent *s = servMgr->servents;
2653 if (s->type == Servent::T_RELAY && s->chanID.isSame(chid) && !s->isPrivate())
2655 Host h = s->getHost();
2657 ChanHit hit = s->serventHit;
2658 if (!hit.relay && hit.numRelays == 0)
2662 //s->thread.active = false;
2663 LOG_DEBUG("unrelayable Servent : %s",hostName);
2664 if (!ks || s->lastConnect < ks->lastConnect) // elder servent
2673 if (sendhit.rhost[0].port)
2676 MemoryStream mem(pack.data,sizeof(pack.data));
2677 AtomStream atom(mem);
2678 sendhit.writeAtoms(atom, chid);
2680 pack.type = ChanPacket::T_PCP;
2684 ks->sendPacket(pack, chid, noID, noID, Servent::T_RELAY);
2687 ks->setStatus(Servent::S_CLOSING);
2688 ks->thread.active = false;
2691 ks->getHost().toStr(hostName);
2693 LOG_DEBUG("Stop unrelayable Servent : %s",hostName);