servmgr.cpp
上传用户:chn_coc
上传日期:2007-12-20
资源大小:563k
文件大小:52k
源码类别:

P2P编程

开发平台:

Windows_Unix

  1. // ------------------------------------------------ // File : servmgr.cpp // Date: 4-apr-2002 // Author: giles // Desc:  // Management class for handling multiple servent connections. // // (c) 2002 peercast.org // ------------------------------------------------ // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the // GNU General Public License for more details. // ------------------------------------------------ #include <stdlib.h> #include "servent.h" #include "servmgr.h" #include "inifile.h" #include "stats.h" #include "peercast.h" #include "pcp.h"
  2. #include "atom.h"
  3. #include "version2.h"
  4. ThreadInfo ServMgr::serverThread,ServMgr::idleThread;
  5. // ----------------------------------- ServMgr::ServMgr() {
  6. validBCID = NULL;
  7. authType = AUTH_COOKIE; cookieList.init(); serventNum = 0; startTime = sys->getTime(); allowServer1 = Servent::ALLOW_ALL; allowServer2 = Servent::ALLOW_BROADCAST; clearHostCache(ServHost::T_NONE); password[0]=0; allowGnutella = false; useFlowControl = true;
  8. maxServIn = 50;
  9. minGnuIncoming = 10;
  10. maxGnuIncoming = 20;
  11. lastIncoming = 0;
  12. maxBitrateOut = 0; maxRelays = MIN_RELAYS; maxDirect = 0;
  13. refreshHTML = 5; networkID.clear(); notifyMask = 0xffff; tryoutDelay = 10; numVersions = 0; sessionID.generate();
  14. isDisabled = false; isRoot = false;
  15. forceIP.clear(); strcpy(connectHost,"connect1.peercast.org");
  16. strcpy(htmlPath,"html/en");
  17. rootHost = "yp.peercast.org";
  18. serverHost.fromStrIP("127.0.0.1",DEFAULT_PORT); firewalled = FW_UNKNOWN; allowDirect = true; autoConnect = true; forceLookup = true; autoServe = true; forceNormal = false;
  19. maxControl = 3;
  20. queryTTL = 7; totalStreams = 0; firewallTimeout = 30; pauseLog = false; showLog = 0; shutdownTimer = 0; downloadURL[0] = 0; rootMsg.clear(); restartServer=false; setFilterDefaults(); servents = NULL; chanLog=""; }
  21. // -----------------------------------
  22. BCID *ServMgr::findValidBCID(int index)
  23. {
  24. int cnt = 0;
  25. BCID *bcid = validBCID;
  26. while (bcid)
  27. {
  28. if (cnt == index)
  29. return bcid;
  30. cnt++;
  31. bcid=bcid->next;
  32. }
  33. return 0;
  34. }
  35. // -----------------------------------
  36. BCID *ServMgr::findValidBCID(GnuID &id)
  37. {
  38. BCID *bcid = validBCID;
  39. while (bcid)
  40. {
  41. if (bcid->id.isSame(id))
  42. return bcid;
  43. bcid=bcid->next;
  44. }
  45. return 0;
  46. }
  47. // -----------------------------------
  48. void ServMgr::removeValidBCID(GnuID &id)
  49. {
  50. BCID *bcid = validBCID,*prev=0;
  51. while (bcid)
  52. {
  53. if (bcid->id.isSame(id))
  54. {
  55. if (prev)
  56. prev->next = bcid->next;
  57. else
  58. validBCID = bcid->next;
  59. return;
  60. }
  61. prev = bcid;
  62. bcid=bcid->next;
  63. }
  64. }
  65. // -----------------------------------
  66. void ServMgr::addValidBCID(BCID *bcid)
  67. {
  68. removeValidBCID(bcid->id);
  69. bcid->next = validBCID;
  70. validBCID = bcid;
  71. }
  72. // -----------------------------------
  73. void ServMgr::connectBroadcaster()
  74. {
  75. if (!rootHost.isEmpty())
  76. {
  77. if (!numUsed(Servent::T_COUT))
  78. {
  79. Servent *sv = allocServent();
  80. if (sv)
  81. {
  82. sv->initOutgoing(Servent::T_COUT);
  83. sys->sleep(3000);
  84. }
  85. }
  86. }
  87. } // ----------------------------------- void ServMgr::addVersion(unsigned int ver) { for(int i=0; i<numVersions; i++) if (clientVersions[i] == ver) { clientCounts[i]++; return; } if (numVersions < MAX_VERSIONS) { clientVersions[numVersions] = ver; clientCounts[numVersions] = 1; numVersions++; } } // ----------------------------------- void ServMgr::setFilterDefaults() { numFilters = 0; filters[numFilters].host.fromStrIP("255.255.255.255",0); filters[numFilters].flags = ServFilter::F_NETWORK|ServFilter::F_DIRECT; numFilters++; }
  88. // -----------------------------------
  89. void ServMgr::setPassiveSearch(unsigned int t) { // if ((t > 0) && (t < 60)) // t = 60; // passiveSearch = t; } // ----------------------------------- bool ServMgr::seenHost(Host &h, ServHost::TYPE type,unsigned int time) { time = sys->getTime()-time; for(int i=0; i<MAX_HOSTCACHE; i++) if (hostCache[i].type == type) if (hostCache[i].host.ip == h.ip) if (hostCache[i].time >= time) return true; return false; } // ----------------------------------- void ServMgr::addHost(Host &h, ServHost::TYPE type, unsigned int time) { int i; if (!h.isValid()) return; ServHost *sh=NULL; for(i=0; i<MAX_HOSTCACHE; i++) if (hostCache[i].type == type) if (hostCache[i].host.isSame(h))
  90. { sh = &hostCache[i]; break; }
  91. char str[64];
  92. h.toStr(str);
  93. if (!sh)
  94. LOG_DEBUG("New host: %s - %s",str,ServHost::getTypeStr(type));
  95. else
  96. LOG_DEBUG("Old host: %s - %s",str,ServHost::getTypeStr(type));
  97. h.value = 0; // make sure dead count is zero if (!sh) { // find empty slot for(i=0; i<MAX_HOSTCACHE; i++) if (hostCache[i].type == ServHost::T_NONE) { sh = &hostCache[i]; break; } // otherwise, find oldest host and replace if (!sh) for(i=0; i<MAX_HOSTCACHE; i++) if (hostCache[i].type != ServHost::T_NONE) { if (sh) { if (hostCache[i].time < sh->time) sh = &hostCache[i]; }else{ sh = &hostCache[i]; } } } if (sh) sh->init(h,type,time); }
  98. // ----------------------------------- void ServMgr::deadHost(Host &h,ServHost::TYPE t) { for(int i=0; i<MAX_HOSTCACHE; i++) if (hostCache[i].type == t) if (hostCache[i].host.ip == h.ip) if (hostCache[i].host.port == h.port) hostCache[i].init(); } // ----------------------------------- void ServMgr::clearHostCache(ServHost::TYPE type) { for(int i=0; i<MAX_HOSTCACHE; i++) if ((hostCache[i].type == type) || (type == ServHost::T_NONE)) hostCache[i].init(); } // ----------------------------------- unsigned int ServMgr::numHosts(ServHost::TYPE type) { unsigned int cnt = 0; for(int i=0; i<MAX_HOSTCACHE; i++) if ((hostCache[i].type == type) || (type == ServHost::T_NONE)) cnt++; return cnt; } // ----------------------------------- int ServMgr::getNewestServents(Host *hl,int max,Host &rh) { int cnt=0; for(int i=0; i<max; i++) { // find newest host not in list ServHost *sh=NULL; for(int j=0; j<MAX_HOSTCACHE; j++) { // find newest servent if (hostCache[j].type == ServHost::T_SERVENT) if (!(rh.globalIP() && !hostCache[j].host.globalIP())) { // and not in list already bool found=false; for(int k=0; k<cnt; k++) if (hl[k].isSame(hostCache[j].host)) { found=true;  break; } if (!found) { if (!sh) { sh = &hostCache[j]; }else{ if (hostCache[j].time > sh->time) sh = &hostCache[j]; } } } } // add to list if (sh) hl[cnt++]=sh->host; } return cnt; } // ----------------------------------- ServHost ServMgr::getOutgoingServent(GnuID &netid) { ServHost host; Host lh(ClientSocket::getIP(NULL),0); // find newest host not in list ServHost *sh=NULL; for(int j=0; j<MAX_HOSTCACHE; j++) { ServHost *hc=&hostCache[j]; // find newest servent not already connected. if (hc->type == ServHost::T_SERVENT) { if (!((lh.globalIP() && !hc->host.globalIP()) || lh.isSame(hc->host))) {
  99. #if 0 if (!findServent(Servent::T_OUTGOING,hc->host,netid)) { if (!sh) { sh = hc; }else{ if (hc->time > sh->time) sh = hc; } }
  100. #endif } } } if (sh) host = *sh; return host; } // ----------------------------------- Servent *ServMgr::findOldestServent(Servent::TYPE type, bool priv) { Servent *oldest=NULL; Servent *s = servents; while (s) { if (s->type == type) if (s->thread.active) if (s->isOlderThan(oldest)) if (s->isPrivate() == priv) oldest = s; s=s->next; } return oldest; } // ----------------------------------- Servent *ServMgr::findServent(Servent::TYPE type, Host &host, GnuID &netid) { lock.on(); Servent *s = servents; while (s) { if (s->type == type) { Host h = s->getHost(); if (h.isSame(host) && s->networkID.isSame(netid)) { lock.off(); return s; } } s=s->next; } lock.off(); return NULL; } // ----------------------------------- Servent *ServMgr::findServent(unsigned int ip, unsigned short port, GnuID &netid) { lock.on(); Servent *s = servents; while (s) { if (s->type != Servent::T_NONE) { Host h = s->getHost(); if ((h.ip == ip) && (h.port == port) && (s->networkID.isSame(netid))) { lock.off(); return s; } } s=s->next; } lock.off(); return NULL; } // ----------------------------------- Servent *ServMgr::findServent(Servent::TYPE t) { Servent *s = servents; while (s) { if (s->type == t) return s; s=s->next; } return NULL; } // ----------------------------------- Servent *ServMgr::findServentByIndex(int id) { Servent *s = servents;
  101. int cnt=0; while (s) {
  102. if (cnt == id)
  103. return s;
  104. cnt++;
  105. s=s->next; } return NULL; } // ----------------------------------- Servent *ServMgr::allocServent() { lock.on(); Servent *s = servents; while (s) { if (s->status == Servent::S_FREE) break; s=s->next; } if (!s) { s = new Servent(++serventNum); s->next = servents; servents = s; LOG_DEBUG("allocated servent %d",serventNum); }else LOG_DEBUG("reused servent %d",s->serventIndex); s->reset(); lock.off(); return s; }
  106. // --------------------------------------------------
  107. void ServMgr::closeConnections(Servent::TYPE type)
  108. {
  109. Servent *sv = servents;
  110. while (sv)
  111. {
  112. if (sv->isConnected())
  113. if (sv->type == type)
  114. sv->thread.active = false;
  115. sv=sv->next;
  116. }
  117. }
  118. // ----------------------------------- unsigned int ServMgr::numConnected(int type,bool priv,unsigned int uptime) { unsigned int cnt=0;
  119. unsigned int ctime=sys->getTime(); Servent *s = servents; while (s) { if (s->thread.active) if (s->isConnected()) if (s->type == type) if (s->isPrivate()==priv)
  120. if ((ctime-s->lastConnect) >= uptime) cnt++; s=s->next; } return cnt; } // -----------------------------------
  121. unsigned int ServMgr::numConnected()
  122. {
  123. unsigned int cnt=0;
  124. Servent *s = servents;
  125. while (s)
  126. {
  127. if (s->thread.active)
  128. if (s->isConnected())
  129. cnt++;
  130. s=s->next;
  131. }
  132. return cnt;
  133. }
  134. // -----------------------------------
  135. unsigned int ServMgr::numServents()
  136. {
  137. unsigned int cnt=0;
  138. Servent *s = servents;
  139. while (s)
  140. {
  141. cnt++;
  142. s=s->next;
  143. }
  144. return cnt;
  145. }
  146. // ----------------------------------- unsigned int ServMgr::numUsed(int type) { unsigned int cnt=0; Servent *s = servents; while (s) { if (s->type == type) cnt++; s=s->next; } return cnt; } // -----------------------------------
  147. unsigned int ServMgr::numActiveOnPort(int port)
  148. {
  149. unsigned int cnt=0;
  150. Servent *s = servents;
  151. while (s)
  152. {
  153. if (s->thread.active && s->sock && (s->servPort == port))
  154. cnt++;
  155. s=s->next;
  156. }
  157. return cnt;
  158. }
  159. // -----------------------------------
  160. unsigned int ServMgr::numActive(Servent::TYPE tp)
  161. {
  162. unsigned int cnt=0;
  163. Servent *s = servents;
  164. while (s)
  165. {
  166. if (s->thread.active && s->sock && (s->type == tp))
  167. cnt++;
  168. s=s->next;
  169. }
  170. return cnt;
  171. }
  172. // ----------------------------------- unsigned int ServMgr::totalOutput(bool all) { unsigned int tot = 0; Servent *s = servents; while (s) { if (s->isConnected())
  173. if (all || !s->isPrivate()) if (s->sock) tot += s->sock->bytesOutPerSec; s=s->next; } return tot; } // ----------------------------------- unsigned int ServMgr::numOutgoing() { int cnt=0; Servent *s = servents; while (s) { // if ((s->type == Servent::T_INCOMING) || //     (s->type == Servent::T_OUTGOING))  // cnt++; s=s->next; } return cnt; } // ----------------------------------- bool ServMgr::seenPacket(GnuPacket &p) { Servent *s = servents; while (s) { if (s->isConnected())
  174. if (s->seenIDs.contains(p.id)) return true; s=s->next; } return false; }
  175. // -----------------------------------
  176. void ServMgr::quit()
  177. {
  178. LOG_DEBUG("ServMgr is quitting..");
  179. serverThread.shutdown();
  180. idleThread.shutdown();
  181. Servent *s = servents;
  182. while (s)
  183. {
  184. try
  185. {
  186. if (s->thread.active)
  187. {
  188. s->thread.shutdown();
  189. }
  190. }catch(StreamException &)
  191. {
  192. }
  193. s=s->next;
  194. }
  195. }
  196. // ----------------------------------- int ServMgr::broadcast(GnuPacket &pack,Servent *src) { int cnt=0; if (pack.ttl) { Servent *s = servents; while (s) { if (s != src) if (s->isConnected())
  197. if (s->type == Servent::T_PGNU) if (!s->seenIDs.contains(pack.id)) { if (src) if (!src->networkID.isSame(s->networkID)) continue; if (s->outputPacket(pack,false)) cnt++; } s=s->next; } } LOG_NETWORK("broadcast: %s (%d) to %d servents",GNU_FUNC_STR(pack.func),pack.ttl,cnt); return cnt; } // ----------------------------------- int ServMgr::route(GnuPacket &pack, GnuID &routeID, Servent *src) { int cnt=0; if (pack.ttl) { Servent *s = servents; while (s) { if (s != src) if (s->isConnected())
  198. if (s->type == Servent::T_PGNU)
  199. if (!s->seenIDs.contains(pack.id)) if (s->seenIDs.contains(routeID)) { if (src) if (!src->networkID.isSame(s->networkID)) continue; if (s->outputPacket(pack,true)) cnt++; } s=s->next; } } LOG_NETWORK("route: %s (%d) to %d servents",GNU_FUNC_STR(pack.func),pack.ttl,cnt); return cnt; }
  200. // -----------------------------------
  201. bool ServMgr::checkForceIP()
  202. {
  203. if (!forceIP.isEmpty())
  204. {
  205. unsigned int newIP = ClientSocket::getIP(forceIP.cstr());
  206. if (serverHost.ip != newIP)
  207. {
  208. serverHost.ip = newIP;
  209. char ipstr[64];
  210. serverHost.IPtoStr(ipstr);
  211. LOG_DEBUG("Server IP changed to %s",ipstr);
  212. return true;
  213. }
  214. }
  215. return false;
  216. }
  217. // -----------------------------------
  218. void ServMgr::checkFirewall()
  219. {
  220. if ((getFirewall() == FW_UNKNOWN) && !servMgr->rootHost.isEmpty())
  221. {
  222. LOG_DEBUG("Checking firewall..");
  223. Host host;
  224. host.fromStrName(servMgr->rootHost.cstr(),DEFAULT_PORT);
  225. ClientSocket *sock = sys->createSocket();
  226. if (!sock)
  227. throw StreamException("Unable to create socket");
  228. sock->setReadTimeout(30000);
  229. sock->open(host);
  230. sock->connect();
  231. AtomStream atom(*sock);
  232. atom.writeInt(PCP_CONNECT,1);
  233. GnuID remoteID;
  234. String agent;
  235. Servent::handshakeOutgoingPCP(atom,sock->host,remoteID,agent,true);
  236. atom.writeInt(PCP_QUIT,PCP_ERROR_QUIT);
  237. sock->close();
  238. delete sock;
  239. }
  240. }
  241. // ----------------------------------- void ServMgr::setFirewall(FW_STATE state) { if (firewalled != state) { char *str; switch (state) { case FW_ON: str = "ON"; break; case FW_OFF: str = "OFF"; break; case FW_UNKNOWN: default: str = "UNKNOWN"; break; } LOG_DEBUG("Firewall is set to %s",str); firewalled = state; } } // ----------------------------------- bool ServMgr::isFiltered(int fl, Host &h) { for(int i=0; i<numFilters; i++) if (filters[i].flags & fl) if (h.isMemberOf(filters[i].host)) return true; return false; } #if 0 // ----------------------------------- bool ServMgr::canServeHost(Host &h) { if (server) { Host sh = server->getHost(); if (sh.globalIP() || (sh.localIP() && h.localIP())) return true; } return false; } #endif // -------------------------------------------------- void writeServerSettings(IniFile &iniFile, unsigned int a) { iniFile.writeBoolValue("allowHTML",a & Servent::ALLOW_HTML); iniFile.writeBoolValue("allowBroadcast",a & Servent::ALLOW_BROADCAST);
  242. iniFile.writeBoolValue("allowNetwork",a & Servent::ALLOW_NETWORK); iniFile.writeBoolValue("allowDirect",a & Servent::ALLOW_DIRECT);
  243. } // -------------------------------------------------- void writeFilterSettings(IniFile &iniFile, ServFilter &f) { char ipstr[64]; f.host.IPtoStr(ipstr); iniFile.writeStrValue("ip",ipstr); iniFile.writeBoolValue("private",f.flags & ServFilter::F_PRIVATE); iniFile.writeBoolValue("ban",f.flags & ServFilter::F_BAN); iniFile.writeBoolValue("network",f.flags & ServFilter::F_NETWORK); iniFile.writeBoolValue("direct",f.flags & ServFilter::F_DIRECT); } // -------------------------------------------------- static void  writeServHost(IniFile &iniFile, ServHost &sh) { iniFile.writeSection("Host"); char ipStr[64]; sh.host.toStr(ipStr); iniFile.writeStrValue("type",ServHost::getTypeStr(sh.type)); iniFile.writeStrValue("address",ipStr); iniFile.writeIntValue("time",sh.time); iniFile.writeLine("[End]"); } // -------------------------------------------------- void ServMgr::saveSettings(const char *fn) { IniFile iniFile; if (!iniFile.openWriteReplace(fn)) { LOG_ERROR("Unable to open ini file"); }else{ LOG_DEBUG("Saving settings to:  %s",fn); char idStr[64]; iniFile.writeSection("Server"); iniFile.writeIntValue("serverPort",servMgr->serverHost.port); iniFile.writeBoolValue("autoServe",servMgr->autoServe); iniFile.writeStrValue("forceIP",servMgr->forceIP); iniFile.writeBoolValue("isRoot",servMgr->isRoot); iniFile.writeIntValue("maxBitrateOut",servMgr->maxBitrateOut); iniFile.writeIntValue("maxRelays",servMgr->maxRelays); iniFile.writeIntValue("maxDirect",servMgr->maxDirect);
  244. iniFile.writeIntValue("maxRelaysPerChannel",chanMgr->maxRelaysPerChannel); iniFile.writeIntValue("firewallTimeout",firewallTimeout); iniFile.writeBoolValue("forceNormal",forceNormal); iniFile.writeStrValue("rootMsg",rootMsg.cstr()); iniFile.writeStrValue("authType",servMgr->authType==ServMgr::AUTH_COOKIE?"cookie":"http-basic"); iniFile.writeStrValue("cookiesExpire",servMgr->cookieList.neverExpire==true?"never":"session"); iniFile.writeStrValue("htmlPath",servMgr->htmlPath);
  245. iniFile.writeIntValue("minPGNUIncoming",servMgr->minGnuIncoming);
  246. iniFile.writeIntValue("maxPGNUIncoming",servMgr->maxGnuIncoming);
  247. iniFile.writeIntValue("maxServIn",servMgr->maxServIn);
  248. iniFile.writeStrValue("chanLog",servMgr->chanLog.cstr()); networkID.toStr(idStr); iniFile.writeStrValue("networkID",idStr);
  249. iniFile.writeSection("Broadcast");
  250. iniFile.writeIntValue("broadcastMsgInterval",chanMgr->broadcastMsgInterval);
  251. iniFile.writeStrValue("broadcastMsg",chanMgr->broadcastMsg.cstr());
  252. iniFile.writeIntValue("icyMetaInterval",chanMgr->icyMetaInterval);
  253. chanMgr->broadcastID.toStr(idStr);
  254. iniFile.writeStrValue("broadcastID",idStr);
  255. iniFile.writeIntValue("hostUpdateInterval",chanMgr->hostUpdateInterval);
  256. iniFile.writeIntValue("maxControlConnections",servMgr->maxControl);
  257. iniFile.writeStrValue("rootHost",servMgr->rootHost.cstr());
  258. iniFile.writeSection("Client"); iniFile.writeIntValue("refreshHTML",refreshHTML); iniFile.writeIntValue("relayBroadcast",servMgr->relayBroadcast); iniFile.writeIntValue("minBroadcastTTL",chanMgr->minBroadcastTTL); iniFile.writeIntValue("maxBroadcastTTL",chanMgr->maxBroadcastTTL); iniFile.writeIntValue("pushTries",chanMgr->pushTries); iniFile.writeIntValue("pushTimeout",chanMgr->pushTimeout); iniFile.writeIntValue("maxPushHops",chanMgr->maxPushHops); iniFile.writeIntValue("autoQuery",chanMgr->autoQuery); iniFile.writeIntValue("queryTTL",servMgr->queryTTL);
  259. iniFile.writeSection("Privacy"); iniFile.writeStrValue("password",servMgr->password); iniFile.writeIntValue("maxUptime",chanMgr->maxUptime); int i; for(i=0; i<servMgr->numFilters; i++) { iniFile.writeSection("Filter"); writeFilterSettings(iniFile,servMgr->filters[i]); iniFile.writeLine("[End]"); } iniFile.writeSection("Notify"); iniFile.writeBoolValue("PeerCast",notifyMask&NT_PEERCAST); iniFile.writeBoolValue("Broadcasters",notifyMask&NT_BROADCASTERS); iniFile.writeBoolValue("TrackInfo",notifyMask&NT_TRACKINFO); iniFile.writeLine("[End]"); iniFile.writeSection("Server1"); writeServerSettings(iniFile,allowServer1); iniFile.writeLine("[End]"); iniFile.writeSection("Server2"); writeServerSettings(iniFile,allowServer2); iniFile.writeLine("[End]"); iniFile.writeSection("Debug"); iniFile.writeBoolValue("logDebug",(showLog&(1<<LogBuffer::T_DEBUG))!=0); iniFile.writeBoolValue("logErrors",(showLog&(1<<LogBuffer::T_ERROR))!=0); iniFile.writeBoolValue("logNetwork",(showLog&(1<<LogBuffer::T_NETWORK))!=0); iniFile.writeBoolValue("logChannel",(showLog&(1<<LogBuffer::T_CHANNEL))!=0); iniFile.writeBoolValue("pauseLog",pauseLog); iniFile.writeIntValue("idleSleepTime",sys->idleSleepTime);
  260. if (servMgr->validBCID)
  261. {
  262. BCID *bcid = servMgr->validBCID;
  263. while (bcid)
  264. {
  265. iniFile.writeSection("ValidBCID");
  266. char idstr[128];
  267. bcid->id.toStr(idstr);
  268. iniFile.writeStrValue("id",idstr);
  269. iniFile.writeStrValue("name",bcid->name.cstr());
  270. iniFile.writeStrValue("email",bcid->email.cstr());
  271. iniFile.writeStrValue("url",bcid->url.cstr());
  272. iniFile.writeBoolValue("valid",bcid->valid);
  273. iniFile.writeLine("[End]");
  274. bcid=bcid->next;
  275. }
  276. }
  277. Channel *c = chanMgr->channel; while (c) { char idstr[64]; if (c->isActive() && c->stayConnected) { c->getIDStr(idstr);
  278. iniFile.writeSection("RelayChannel"); iniFile.writeStrValue("name",c->getName()); iniFile.writeStrValue("genre",c->info.genre.cstr()); if (!c->sourceURL.isEmpty()) iniFile.writeStrValue("sourceURL",c->sourceURL.cstr()); iniFile.writeStrValue("sourceProtocol",ChanInfo::getProtocolStr(c->info.srcProtocol)); iniFile.writeStrValue("contentType",ChanInfo::getTypeStr(c->info.contentType)); iniFile.writeIntValue("bitrate",c->info.bitrate); iniFile.writeStrValue("contactURL",c->info.url.cstr()); iniFile.writeStrValue("id",idstr); iniFile.writeBoolValue("stayConnected",c->stayConnected);
  279. ChanHitList *chl = chanMgr->findHitListByID(c->info.id);
  280. if (chl)
  281. {
  282. ChanHitSearch chs;
  283. chs.trackersOnly = true;
  284. if (chl->pickHits(chs))
  285. {
  286. char ipStr[64];
  287. chs.best[0].host.toStr(ipStr);
  288. iniFile.writeStrValue("tracker",ipStr);
  289. }
  290. } iniFile.writeLine("[End]"); }
  291. c=c->next; } #if 0 Servent *s = servents; while (s) { if (s->type == Servent::T_OUTGOING) if (s->isConnected())
  292. { ServHost sh; Host h = s->getHost(); sh.init(h,ServHost::T_SERVENT,0,s->networkID); writeServHost(iniFile,sh); } s=s->next; } #endif
  293. for(i=0; i<ServMgr::MAX_HOSTCACHE; i++) { ServHost *sh = &servMgr->hostCache[i]; if (sh->type != ServHost::T_NONE) writeServHost(iniFile,*sh); } iniFile.close(); } } // -------------------------------------------------- unsigned int readServerSettings(IniFile &iniFile, unsigned int a) { while (iniFile.readNext()) { if (iniFile.isName("[End]")) break; else if (iniFile.isName("allowHTML")) a = iniFile.getBoolValue()?a|Servent::ALLOW_HTML:a&~Servent::ALLOW_HTML; else if (iniFile.isName("allowDirect")) a = iniFile.getBoolValue()?a|Servent::ALLOW_DIRECT:a&~Servent::ALLOW_DIRECT; else if (iniFile.isName("allowNetwork")) a = iniFile.getBoolValue()?a|Servent::ALLOW_NETWORK:a&~Servent::ALLOW_NETWORK; else if (iniFile.isName("allowBroadcast")) a = iniFile.getBoolValue()?a|Servent::ALLOW_BROADCAST:a&~Servent::ALLOW_BROADCAST; } return a; } // -------------------------------------------------- void readFilterSettings(IniFile &iniFile, ServFilter &sv) { sv.host.init(); while (iniFile.readNext()) { if (iniFile.isName("[End]")) break; else if (iniFile.isName("ip")) sv.host.fromStrIP(iniFile.getStrValue(),0); else if (iniFile.isName("private")) sv.flags = (sv.flags & ~ServFilter::F_PRIVATE) | (iniFile.getBoolValue()?ServFilter::F_PRIVATE:0); else if (iniFile.isName("ban")) sv.flags = (sv.flags & ~ServFilter::F_BAN) | (iniFile.getBoolValue()?ServFilter::F_BAN:0); else if (iniFile.isName("allow") || iniFile.isName("network")) sv.flags = (sv.flags & ~ServFilter::F_NETWORK) | (iniFile.getBoolValue()?ServFilter::F_NETWORK:0); else if (iniFile.isName("direct")) sv.flags = (sv.flags & ~ServFilter::F_DIRECT) | (iniFile.getBoolValue()?ServFilter::F_DIRECT:0); } } // -------------------------------------------------- void ServMgr::loadSettings(const char *fn) { IniFile iniFile; if (!iniFile.openReadOnly(fn)) saveSettings(fn); servMgr->numFilters = 0; showLog = 0; if (iniFile.openReadOnly(fn)) { while (iniFile.readNext()) { // server settings if (iniFile.isName("serverPort")) servMgr->serverHost.port = iniFile.getIntValue(); else if (iniFile.isName("autoServe")) servMgr->autoServe = iniFile.getBoolValue(); else if (iniFile.isName("autoConnect")) servMgr->autoConnect = iniFile.getBoolValue(); else if (iniFile.isName("icyPassword")) // depreciated strcpy(servMgr->password,iniFile.getStrValue()); else if (iniFile.isName("forceIP")) servMgr->forceIP = iniFile.getStrValue();
  294. else if (iniFile.isName("isRoot")) servMgr->isRoot = iniFile.getBoolValue(); else if (iniFile.isName("broadcastID"))
  295. { chanMgr->broadcastID.fromStr(iniFile.getStrValue());
  296. chanMgr->broadcastID.id[0] = PCP_BROADCAST_FLAGS; // hacky, but we need to fix old clients
  297. }else if (iniFile.isName("htmlPath"))
  298. strcpy(servMgr->htmlPath,iniFile.getStrValue());
  299. else if (iniFile.isName("maxPGNUIncoming"))
  300. servMgr->maxGnuIncoming = iniFile.getIntValue();
  301. else if (iniFile.isName("minPGNUIncoming"))
  302. servMgr->minGnuIncoming = iniFile.getIntValue();
  303. else if (iniFile.isName("maxControlConnections"))
  304. {
  305. servMgr->maxControl = iniFile.getIntValue();
  306. } else if (iniFile.isName("maxBitrateOut")) servMgr->maxBitrateOut = iniFile.getIntValue();
  307. else if (iniFile.isName("maxStreamsOut")) // depreciated servMgr->setMaxRelays(iniFile.getIntValue());
  308. else if (iniFile.isName("maxRelays"))
  309. servMgr->setMaxRelays(iniFile.getIntValue());
  310. else if (iniFile.isName("maxDirect"))
  311. servMgr->maxDirect = iniFile.getIntValue();
  312. else if (iniFile.isName("maxStreamsPerChannel")) // depreciated chanMgr->maxRelaysPerChannel = iniFile.getIntValue(); else if (iniFile.isName("maxRelaysPerChannel"))
  313. chanMgr->maxRelaysPerChannel = iniFile.getIntValue();
  314. else if (iniFile.isName("firewallTimeout")) firewallTimeout = iniFile.getIntValue(); else if (iniFile.isName("forceNormal")) forceNormal = iniFile.getBoolValue(); else if (iniFile.isName("broadcastMsgInterval")) chanMgr->broadcastMsgInterval = iniFile.getIntValue(); else if (iniFile.isName("broadcastMsg")) chanMgr->broadcastMsg.set(iniFile.getStrValue(),String::T_ASCII); else if (iniFile.isName("hostUpdateInterval"))
  315. chanMgr->hostUpdateInterval = iniFile.getIntValue();
  316. else if (iniFile.isName("icyMetaInterval")) chanMgr->icyMetaInterval = iniFile.getIntValue();
  317. else if (iniFile.isName("maxServIn"))
  318. servMgr->maxServIn = iniFile.getIntValue();
  319. else if (iniFile.isName("chanLog")) servMgr->chanLog.set(iniFile.getStrValue(),String::T_ASCII); else if (iniFile.isName("rootMsg")) rootMsg.set(iniFile.getStrValue()); else if (iniFile.isName("networkID")) networkID.fromStr(iniFile.getStrValue()); else if (iniFile.isName("authType")) { char *t = iniFile.getStrValue(); if (stricmp(t,"cookie")==0) servMgr->authType = ServMgr::AUTH_COOKIE; else if (stricmp(t,"http-basic")==0) servMgr->authType = ServMgr::AUTH_HTTPBASIC; }else if (iniFile.isName("cookiesExpire")) { char *t = iniFile.getStrValue(); if (stricmp(t,"never")==0) servMgr->cookieList.neverExpire = true; else if (stricmp(t,"session")==0) servMgr->cookieList.neverExpire = false; } // privacy settings else if (iniFile.isName("password")) strcpy(servMgr->password,iniFile.getStrValue()); else if (iniFile.isName("maxUptime")) chanMgr->maxUptime = iniFile.getIntValue(); // client settings
  320. else if (iniFile.isName("rootHost"))
  321. {
  322. if (!PCP_FORCE_YP)
  323. servMgr->rootHost = iniFile.getStrValue();
  324. }else if (iniFile.isName("deadHitAge")) chanMgr->deadHitAge = iniFile.getIntValue(); else if (iniFile.isName("tryoutDelay")) servMgr->tryoutDelay = iniFile.getIntValue(); else if (iniFile.isName("refreshHTML")) refreshHTML = iniFile.getIntValue(); else if (iniFile.isName("relayBroadcast")) { servMgr->relayBroadcast = iniFile.getIntValue(); if (servMgr->relayBroadcast < 30) servMgr->relayBroadcast = 30; } else if (iniFile.isName("minBroadcastTTL")) chanMgr->minBroadcastTTL = iniFile.getIntValue(); else if (iniFile.isName("maxBroadcastTTL")) chanMgr->maxBroadcastTTL = iniFile.getIntValue(); else if (iniFile.isName("pushTimeout")) chanMgr->pushTimeout = iniFile.getIntValue(); else if (iniFile.isName("pushTries")) chanMgr->pushTries = iniFile.getIntValue(); else if (iniFile.isName("maxPushHops")) chanMgr->maxPushHops = iniFile.getIntValue(); else if (iniFile.isName("autoQuery")) { chanMgr->autoQuery = iniFile.getIntValue(); if ((chanMgr->autoQuery < 300) && (chanMgr->autoQuery > 0)) chanMgr->autoQuery = 300; } else if (iniFile.isName("queryTTL")) { servMgr->queryTTL = iniFile.getIntValue(); } // debug else if (iniFile.isName("logDebug")) showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_DEBUG:0; else if (iniFile.isName("logErrors")) showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_ERROR:0; else if (iniFile.isName("logNetwork")) showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_NETWORK:0; else if (iniFile.isName("logChannel")) showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_CHANNEL:0; else if (iniFile.isName("pauseLog")) pauseLog = iniFile.getBoolValue(); else if (iniFile.isName("idleSleepTime")) sys->idleSleepTime = iniFile.getIntValue(); else if (iniFile.isName("[Server1]")) allowServer1 = readServerSettings(iniFile,allowServer1); else if (iniFile.isName("[Server2]")) allowServer2 = readServerSettings(iniFile,allowServer2); else if (iniFile.isName("[Filter]")) { readFilterSettings(iniFile,filters[numFilters]); if (numFilters < (MAX_FILTERS-1)) numFilters++; } else if (iniFile.isName("[Notify]")) { notifyMask = NT_UPGRADE; while (iniFile.readNext()) { if (iniFile.isName("[End]")) break; else if (iniFile.isName("PeerCast")) notifyMask |= iniFile.getBoolValue()?NT_PEERCAST:0; else if (iniFile.isName("Broadcasters")) notifyMask |= iniFile.getBoolValue()?NT_BROADCASTERS:0; else if (iniFile.isName("TrackInfo")) notifyMask |= iniFile.getBoolValue()?NT_TRACKINFO:0; } } else if (iniFile.isName("[RelayChannel]")) { ChanInfo info; bool stayConnected=false; String sourceURL; while (iniFile.readNext()) { if (iniFile.isName("[End]")) break; else if (iniFile.isName("name")) info.name.set(iniFile.getStrValue()); else if (iniFile.isName("id")) info.id.fromStr(iniFile.getStrValue()); else if (iniFile.isName("sourceType")) info.srcProtocol = ChanInfo::getProtocolFromStr(iniFile.getStrValue()); else if (iniFile.isName("contentType")) info.contentType = ChanInfo::getTypeFromStr(iniFile.getStrValue()); else if (iniFile.isName("stayConnected")) stayConnected = iniFile.getBoolValue(); else if (iniFile.isName("sourceURL")) sourceURL.set(iniFile.getStrValue()); else if (iniFile.isName("genre")) info.genre.set(iniFile.getStrValue()); else if (iniFile.isName("contactURL")) info.url.set(iniFile.getStrValue()); else if (iniFile.isName("bitrate")) info.bitrate = atoi(iniFile.getStrValue()); else if (iniFile.isName("tracker"))
  325. {
  326. ChanHit hit;
  327. hit.init();
  328. hit.tracker = true;
  329. hit.host.fromStrName(iniFile.getStrValue(),DEFAULT_PORT);
  330. hit.rhost[0] = hit.host;
  331. hit.rhost[1] = hit.host;
  332. hit.chanID = info.id;
  333. hit.recv = true;
  334. chanMgr->addHit(hit);
  335. }
  336. } if (sourceURL.isEmpty()) { chanMgr->createRelay(info,stayConnected); }else {
  337. info.bcID = chanMgr->broadcastID; Channel *c = chanMgr->createChannel(info,NULL); if (c) c->startURL(sourceURL.cstr()); } } else if (iniFile.isName("[Host]")) { Host h; ServHost::TYPE type=ServHost::T_NONE;
  338. bool firewalled=false; unsigned int time=0; while (iniFile.readNext()) { if (iniFile.isName("[End]")) break; else if (iniFile.isName("address")) h.fromStrIP(iniFile.getStrValue(),DEFAULT_PORT); else if (iniFile.isName("type")) type = ServHost::getTypeFromStr(iniFile.getStrValue()); else if (iniFile.isName("time")) time = iniFile.getIntValue(); } servMgr->addHost(h,type,time); } else if (iniFile.isName("[ValidBCID]"))
  339. {
  340. BCID *bcid = new BCID();
  341. while (iniFile.readNext())
  342. {
  343. if (iniFile.isName("[End]"))
  344. break;
  345. else if (iniFile.isName("id"))
  346. bcid->id.fromStr(iniFile.getStrValue());
  347. else if (iniFile.isName("name"))
  348. bcid->name.set(iniFile.getStrValue());
  349. else if (iniFile.isName("email"))
  350. bcid->email.set(iniFile.getStrValue());
  351. else if (iniFile.isName("url"))
  352. bcid->url.set(iniFile.getStrValue());
  353. else if (iniFile.isName("valid"))
  354. bcid->valid = iniFile.getBoolValue();
  355. }
  356. servMgr->addValidBCID(bcid);
  357. } } } if (!numFilters) setFilterDefaults();
  358. }
  359. // --------------------------------------------------
  360. unsigned int ServMgr::numStreams(GnuID &cid, Servent::TYPE tp, bool all)
  361. {
  362. int cnt = 0;
  363. Servent *sv = servents;
  364. while (sv)
  365. {
  366. if (sv->isConnected())
  367. if (sv->type == tp)
  368. if (sv->chanID.isSame(cid))
  369. if (all || !sv->isPrivate())
  370. cnt++;
  371. sv=sv->next;
  372. }
  373. return cnt;
  374. }
  375. // --------------------------------------------------
  376. unsigned int ServMgr::numStreams(Servent::TYPE tp, bool all)
  377. {
  378. int cnt = 0;
  379. Servent *sv = servents;
  380. while (sv)
  381. {
  382. if (sv->isConnected())
  383. if (sv->type == tp)
  384. if (all || !sv->isPrivate())
  385. cnt++;
  386. sv=sv->next;
  387. }
  388. return cnt;
  389. }
  390. // --------------------------------------------------
  391. bool ServMgr::getChannel(char *str,ChanInfo &info, bool relay)
  392. {
  393. // remove file extension (only added for winamp)
  394. //char *ext = strstr(str,".");
  395. //if (ext) *ext = 0;
  396. procConnectArgs(str,info);
  397. Channel *ch;
  398. ch = chanMgr->findChannelByNameID(info);
  399. if (ch)
  400. {
  401. if (!ch->isPlaying())
  402. {
  403. if (relay)
  404. {
  405. ch->info.lastPlayStart = 0; // force reconnect 
  406. ch->info.lastPlayEnd = 0; 
  407. }else
  408. return false;
  409. }
  410. info = ch->info; // get updated channel info 
  411. return true;
  412. }else
  413. {
  414. if (relay)
  415. {
  416. ch = chanMgr->findAndRelay(info);
  417. if (ch)
  418. {
  419. info = ch->info; //get updated channel info 
  420. return true;
  421. }
  422. }
  423. }
  424. return false;
  425. }
  426. // -------------------------------------------------- int ServMgr::findChannel(ChanInfo &info) {
  427. #if 0 char idStr[64]; info.id.toStr(idStr); if (info.id.isSet()) { // if we have an ID then try and connect to known hosts carrying channel. ServHost sh = getOutgoingServent(info.id); addOutgoing(sh.host,info.id,true); } GnuPacket pack; XML xml; XML::Node *n = info.createQueryXML(); xml.setRoot(n); pack.initFind(NULL,&xml,servMgr->queryTTL); addReplyID(pack.id); int cnt = broadcast(pack,NULL); LOG_NETWORK("Querying network: %s %s - %d servents",info.name.cstr(),idStr,cnt); return cnt;
  428. #endif
  429. return 0; } // -------------------------------------------------- // add outgoing network connection from string (ip:port format) bool ServMgr::addOutgoing(Host h, GnuID &netid, bool pri) {
  430. #if 0 if (h.ip) { if (!findServent(h.ip,h.port,netid)) { Servent *sv = allocServent(); if (sv) { if (pri) sv->priorityConnect = true; sv->networkID = netid; sv->initOutgoing(h,Servent::T_OUTGOING); return true; } } } #endif
  431. return false; } // --------------------------------------------------
  432. Servent *ServMgr::findConnection(Servent::TYPE t,GnuID &sid)
  433. {
  434. Servent *sv = servents;
  435. while (sv)
  436. {
  437. if (sv->isConnected())
  438. if (sv->type == t)
  439. if (sv->remoteID.isSame(sid))
  440. return sv;
  441. sv=sv->next;
  442. }
  443. return NULL;
  444. }
  445. // -------------------------------------------------- void ServMgr::procConnectArgs(char *str,ChanInfo &info) { char arg[512]; char curr[256];
  446. char *args = strstr(str,"?");
  447. if (args)
  448. *args++=0;
  449. info.initNameID(str);
  450. if (args) { while (args=nextCGIarg(args,curr,arg)) {
  451. LOG_DEBUG("cmd: %s, arg: %s",curr,arg);
  452. if (strcmp(curr,"sip")==0) // sip - add network connection to client with channel
  453. { Host h; h.fromStrName(arg,DEFAULT_PORT); if (addOutgoing(h,servMgr->networkID,true)) LOG_NETWORK("Added connection: %s",arg); }else if (strcmp(curr,"pip")==0) // pip - add private network connection to client with channel
  454. { Host h; h.fromStrName(arg,DEFAULT_PORT); if (addOutgoing(h,info.id,true)) LOG_NETWORK("Added private connection: %s",arg); }else if (strcmp(curr,"ip")==0)
  455. // ip - add hit
  456. {
  457. Host h;
  458. h.fromStrName(arg,DEFAULT_PORT);
  459. ChanHit hit;
  460. hit.init();
  461. hit.host = h; 
  462. hit.rhost[0] = h;
  463. hit.rhost[1].init();
  464. hit.chanID = info.id;
  465. hit.recv = true;
  466. chanMgr->addHit(hit);
  467. }else if (strcmp(curr,"tip")==0)
  468. // tip - add tracker hit
  469. {
  470. Host h;
  471. h.fromStrName(arg,DEFAULT_PORT);
  472. chanMgr->addHit(h,info.id,true);
  473. }
  474. } } } // -------------------------------------------------- bool ServMgr::start() {
  475. char idStr[64];
  476. sessionID.toStr(idStr);
  477. LOG_DEBUG("SessionID: %s",idStr);
  478. checkForceIP();
  479. serverThread.func = ServMgr::serverProc; if (!sys->startThread(&serverThread)) return false;
  480. idleThread.func = ServMgr::idleProc; if (!sys->startThread(&idleThread)) return false; return true; } // -------------------------------------------------- int ServMgr::clientProc(ThreadInfo *thread) {
  481. #if 0 thread->lock(); GnuID netID; netID = servMgr->networkID; while(thread->active) { if (servMgr->autoConnect) { if (servMgr->needConnections() || servMgr->forceLookup) { if (servMgr->needHosts() || servMgr->forceLookup) { // do lookup to find some hosts Host lh; lh.fromStrName(servMgr->connectHost,DEFAULT_PORT); if (!servMgr->findServent(lh.ip,lh.port,netID)) { Servent *sv = servMgr->allocServent(); if (sv) { LOG_DEBUG("Lookup: %s",servMgr->connectHost); sv->networkID = netID; sv->initOutgoing(lh,Servent::T_LOOKUP); servMgr->forceLookup = false; } } } for(int i=0; i<MAX_TRYOUT; i++) { if (servMgr->outUsedFull()) break; if (servMgr->tryFull()) break; ServHost sh = servMgr->getOutgoingServent(netID); if (!servMgr->addOutgoing(sh.host,netID,false)) servMgr->deadHost(sh.host,ServHost::T_SERVENT); sys->sleep(servMgr->tryoutDelay); break; } } }else{
  482. #if 0 Servent *s = servMgr->servents; while (s) { if (s->type == Servent::T_OUTGOING)  s->thread.active = false; s=s->next; }
  483. #endif } sys->sleepIdle(); } thread->unlock();
  484. #endif return 0; }
  485. // -----------------------------------
  486. bool ServMgr::acceptGIV(ClientSocket *sock)
  487. {
  488. Servent *sv = servents;
  489. while (sv)
  490. {
  491. if (sv->type == Servent::T_COUT)
  492. {
  493. if (sv->acceptGIV(sock))
  494. return true;
  495. }
  496. sv=sv->next;
  497. }
  498. return false;
  499. }
  500. // -----------------------------------
  501. int ServMgr::broadcastPushRequest(ChanHit &hit, Host &to, GnuID &chanID, Servent::TYPE type)
  502. {
  503. ChanPacket pack;
  504. MemoryStream pmem(pack.data,sizeof(pack.data));
  505. AtomStream atom(pmem);
  506. atom.writeParent(PCP_BCST,7);
  507. atom.writeChar(PCP_BCST_GROUP,PCP_BCST_GROUP_ALL);
  508. atom.writeChar(PCP_BCST_HOPS,0);
  509. atom.writeChar(PCP_BCST_TTL,7);
  510. atom.writeBytes(PCP_BCST_DEST,hit.sessionID.id,16);
  511. atom.writeBytes(PCP_BCST_FROM,servMgr->sessionID.id,16);
  512. atom.writeInt(PCP_BCST_VERSION,PCP_CLIENT_VERSION);
  513. atom.writeParent(PCP_PUSH,3);
  514. atom.writeInt(PCP_PUSH_IP,to.ip);
  515. atom.writeShort(PCP_PUSH_PORT,to.port);
  516. atom.writeBytes(PCP_PUSH_CHANID,chanID.id,16);
  517. pack.len = pmem.pos;
  518. pack.type = ChanPacket::T_PCP;
  519. GnuID noID;
  520. noID.clear();
  521. return servMgr->broadcastPacket(pack,noID,servMgr->sessionID,hit.sessionID,type);
  522. }
  523. // --------------------------------------------------
  524. void ServMgr::writeRootAtoms(AtomStream &atom, bool getUpdate)
  525. {
  526. atom.writeParent(PCP_ROOT,5 + (getUpdate?1:0));
  527. atom.writeInt(PCP_ROOT_UPDINT,chanMgr->hostUpdateInterval);
  528. atom.writeString(PCP_ROOT_URL,"download.php");
  529. atom.writeInt(PCP_ROOT_CHECKVER,PCP_ROOT_VERSION);
  530. atom.writeInt(PCP_ROOT_NEXT,chanMgr->hostUpdateInterval);
  531. atom.writeString(PCP_MESG_ASCII,rootMsg.cstr());
  532. if (getUpdate)
  533. atom.writeParent(PCP_ROOT_UPDATE,0);
  534. }
  535. // --------------------------------------------------
  536. void ServMgr::broadcastRootSettings(bool getUpdate)
  537. {
  538. if (isRoot)
  539. {
  540. ChanPacket pack;
  541. MemoryStream mem(pack.data,sizeof(pack.data));
  542. AtomStream atom(mem);
  543. atom.writeParent(PCP_BCST,6);
  544. atom.writeChar(PCP_BCST_GROUP,PCP_BCST_GROUP_TRACKERS);
  545. atom.writeChar(PCP_BCST_HOPS,0);
  546. atom.writeChar(PCP_BCST_TTL,7);
  547. atom.writeBytes(PCP_BCST_FROM,sessionID.id,16);
  548. atom.writeInt(PCP_BCST_VERSION,PCP_CLIENT_VERSION);
  549. writeRootAtoms(atom,getUpdate);
  550. mem.len = mem.pos;
  551. mem.rewind();
  552. pack.len = mem.len;
  553. GnuID noID;
  554. noID.clear();
  555. broadcastPacket(pack,noID,servMgr->sessionID,noID,Servent::T_CIN);
  556. }
  557. }
  558. // --------------------------------------------------
  559. int ServMgr::broadcastPacket(ChanPacket &pack,GnuID &chanID,GnuID &srcID, GnuID &destID, Servent::TYPE type)
  560. {
  561. int cnt=0;
  562. Servent *sv = servents;
  563. while (sv)
  564. {
  565. if (sv->sendPacket(pack,chanID,srcID,destID,type))
  566. cnt++;
  567. sv=sv->next;
  568. }
  569. return cnt;
  570. }
  571. // -------------------------------------------------- int ServMgr::idleProc(ThreadInfo *thread) { // thread->lock(); unsigned int lastPasvFind=0; unsigned int lastBroadcast=0; // nothing much to do for the first couple of seconds, so just hang around. sys->sleep(2000); unsigned int lastBWcheck=0; unsigned int bytesIn=0,bytesOut=0;
  572. unsigned int lastBroadcastConnect = 0;
  573. unsigned int lastRootBroadcast = 0;
  574. unsigned int lastForceIPCheck = 0;
  575. while(thread->active) { stats.update();
  576. unsigned int ctime = sys->getTime();
  577. if (!servMgr->forceIP.isEmpty())
  578. {
  579. if ((ctime-lastForceIPCheck) > 60)
  580. {
  581. if (servMgr->checkForceIP())
  582. {
  583. GnuID noID;
  584. noID.clear();
  585. chanMgr->broadcastTrackerUpdate(noID,true);
  586. }
  587. lastForceIPCheck = ctime;
  588. }
  589. }
  590. if (chanMgr->isBroadcasting())
  591. {
  592. if ((ctime-lastBroadcastConnect) > 30)
  593. {
  594. servMgr->connectBroadcaster();
  595. lastBroadcastConnect = ctime;
  596. }
  597. }
  598. if (servMgr->isRoot)
  599. {
  600. if ((servMgr->lastIncoming) && ((ctime-servMgr->lastIncoming) > 60*60))
  601. {
  602. peercastInst->saveSettings();
  603. sys->exit();
  604. }
  605. if ((ctime-lastRootBroadcast) > chanMgr->hostUpdateInterval)
  606. {
  607. servMgr->broadcastRootSettings(true);
  608. lastRootBroadcast = ctime;
  609. }
  610. }
  611. // clear dead hits
  612. chanMgr->clearDeadHits(true); if (servMgr->shutdownTimer) { if (--servMgr->shutdownTimer <= 0) { peercastInst->saveSettings(); sys->exit(); } }
  613. // shutdown idle channels if (chanMgr->numIdleChannels() > ChanMgr::MAX_IDLE_CHANNELS)
  614. chanMgr->closeOldestIdle();
  615. sys->sleep(500); }
  616. sys->endThread(thread);
  617. // thread->unlock(); return 0; } // -------------------------------------------------- int ServMgr::serverProc(ThreadInfo *thread) {
  618. // thread->lock(); Servent *serv = servMgr->allocServent(); Servent *serv2 = servMgr->allocServent(); unsigned int lastLookupTime=0; while (thread->active) { if (servMgr->restartServer) { serv->abort(); // force close serv2->abort(); // force close
  619. servMgr->quit(); servMgr->restartServer = false; } if (servMgr->autoServe) { serv->allow = servMgr->allowServer1; serv2->allow = servMgr->allowServer2; if ((!serv->sock) || (!serv2->sock)) { LOG_DEBUG("Starting servers"); // servMgr->forceLookup = true; //if (servMgr->serverHost.ip != 0) { if (servMgr->forceNormal) servMgr->setFirewall(ServMgr::FW_OFF); else servMgr->setFirewall(ServMgr::FW_UNKNOWN); Host h = servMgr->serverHost; if (!serv->sock) serv->initServer(h); h.port++; if (!serv2->sock) serv2->initServer(h); } } }else{ // stop server serv->abort(); // force close serv2->abort(); // force close // cancel incoming connectuions Servent *s = servMgr->servents; while (s) { if (s->type == Servent::T_INCOMING) s->thread.active = false; s=s->next; } servMgr->setFirewall(ServMgr::FW_ON); } sys->sleepIdle(); }
  620. sys->endThread(thread);
  621. // thread->unlock(); return 0; }
  622. // -----------------------------------
  623. void ServMgr::setMaxRelays(int max)
  624. {
  625. if (max < MIN_RELAYS)
  626. max = MIN_RELAYS;
  627. maxRelays = max;
  628. }
  629. // ----------------------------------- XML::Node *ServMgr::createServentXML() { return new XML::Node("servent agent="%s" ",PCX_AGENT); } // -------------------------------------------------- const char *ServHost::getTypeStr(TYPE t) { switch(t) { case T_NONE: return "NONE"; case T_STREAM: return "STREAM"; case T_CHANNEL: return "CHANNEL"; case T_SERVENT: return "SERVENT"; case T_TRACKER: return "TRACKER";
  630. } return "UNKNOWN"; } // -------------------------------------------------- ServHost::TYPE ServHost::getTypeFromStr(const char *s) { if (stricmp(s,"NONE")==0) return T_NONE; else if (stricmp(s,"SERVENT")==0) return T_SERVENT; else if (stricmp(s,"STREAM")==0) return T_STREAM; else if (stricmp(s,"CHANNEL")==0) return T_CHANNEL; else if (stricmp(s,"TRACKER")==0)
  631. return T_TRACKER;
  632. return T_NONE; }
  633. // --------------------------------------------------
  634. bool ServFilter::writeVariable(Stream &out, const String &var)
  635. {
  636. char buf[1024];
  637. if (var == "network")
  638. strcpy(buf,(flags & F_NETWORK)?"1":"0");
  639. else if (var == "private")
  640. strcpy(buf,(flags & F_PRIVATE)?"1":"0");
  641. else if (var == "direct")
  642. strcpy(buf,(flags & F_DIRECT)?"1":"0");
  643. else if (var == "banned")
  644. strcpy(buf,(flags & F_BAN)?"1":"0");
  645. else if (var == "ip")
  646. host.IPtoStr(buf);
  647. else
  648. return false;
  649. out.writeString(buf);
  650. return true;
  651. }
  652. // --------------------------------------------------
  653. bool BCID::writeVariable(Stream &out, const String &var)
  654. {
  655. char buf[1024];
  656. if (var == "id")
  657. id.toStr(buf);
  658. else if (var == "name")
  659. strcpy(buf,name.cstr());
  660. else if (var == "email")
  661. strcpy(buf,email.cstr());
  662. else if (var == "url")
  663. strcpy(buf,url.cstr());
  664. else if (var == "valid")
  665. strcpy(buf,valid?"Yes":"No");
  666. else
  667. return false;
  668. out.writeString(buf);
  669. return true;
  670. }
  671. // --------------------------------------------------
  672. bool ServMgr::writeVariable(Stream &out, const String &var)
  673. {
  674. char buf[1024];
  675. String str;
  676. if (var == "version")
  677. strcpy(buf,PCX_VERSTRING);
  678. else if (var == "uptime")
  679. {
  680. str.setFromStopwatch(getUptime());
  681. str.convertTo(String::T_HTML);
  682. strcpy(buf,str.cstr());
  683. }else if (var == "numRelays")
  684. sprintf(buf,"%d",numStreams(Servent::T_RELAY,true));
  685. else if (var == "numDirect")
  686. sprintf(buf,"%d",numStreams(Servent::T_DIRECT,true));
  687. else if (var == "totalConnected")
  688. sprintf(buf,"%d",totalConnected());
  689. else if (var == "numServHosts")
  690. sprintf(buf,"%d",numHosts(ServHost::T_SERVENT));
  691. else if (var == "numServents")
  692. sprintf(buf,"%d",numServents());
  693. else if (var == "serverPort")
  694. sprintf(buf,"%d",serverHost.port);
  695. else if (var == "serverIP")
  696. serverHost.IPtoStr(buf);
  697. else if (var == "ypAddress")
  698. strcpy(buf,rootHost.cstr());
  699. else if (var == "password")
  700. strcpy(buf,password);
  701. else if (var == "isFirewalled")
  702. sprintf(buf,"%d",getFirewall()==FW_ON?1:0);
  703. else if (var == "firewallKnown")
  704. sprintf(buf,"%d",getFirewall()==FW_UNKNOWN?0:1);
  705. else if (var == "rootMsg")
  706. strcpy(buf,rootMsg);
  707. else if (var == "isRoot")
  708. sprintf(buf,"%d",isRoot?1:0);
  709. else if (var == "isPrivate")
  710. sprintf(buf,"%d",(PCP_BROADCAST_FLAGS&1)?1:0);
  711. else if (var == "forceYP")
  712. sprintf(buf,"%d",PCP_FORCE_YP?1:0);
  713. else if (var == "refreshHTML")
  714. sprintf(buf,"%d",refreshHTML?refreshHTML:0x0fffffff);
  715. else if (var == "maxRelays")
  716. sprintf(buf,"%d",maxRelays);
  717. else if (var == "maxDirect")
  718. sprintf(buf,"%d",maxDirect);
  719. else if (var == "maxBitrateOut")
  720. sprintf(buf,"%d",maxBitrateOut);
  721. else if (var == "maxControlsIn")
  722. sprintf(buf,"%d",maxControl);
  723. else if (var == "numFilters")
  724. sprintf(buf,"%d",numFilters+1);
  725. else if (var == "maxPGNUIn")
  726. sprintf(buf,"%d",maxGnuIncoming);
  727. else if (var == "minPGNUIn")
  728. sprintf(buf,"%d",minGnuIncoming);
  729. else if (var == "numActive1")
  730. sprintf(buf,"%d",numActiveOnPort(serverHost.port));
  731. else if (var == "numActive2")
  732. sprintf(buf,"%d",numActiveOnPort(serverHost.port+1));
  733. else if (var == "numPGNU")
  734. sprintf(buf,"%d",numConnected(Servent::T_PGNU));
  735. else if (var == "numCIN")
  736. sprintf(buf,"%d",numConnected(Servent::T_CIN));
  737. else if (var == "numCOUT")
  738. sprintf(buf,"%d",numConnected(Servent::T_COUT));
  739. else if (var == "numIncoming")
  740. sprintf(buf,"%d",numActive(Servent::T_INCOMING));
  741. else if (var == "numValidBCID")
  742. {
  743. int cnt = 0;
  744. BCID *bcid = validBCID;
  745. while (bcid)
  746. {
  747. cnt++;
  748. bcid=bcid->next;
  749. }
  750. sprintf(buf,"%d",cnt);
  751. }
  752. else if (var == "disabled")
  753. sprintf(buf,"%d",isDisabled);
  754. else if (var == "serverPort1")
  755. sprintf(buf,"%d",serverHost.port);
  756. else if (var == "serverLocalIP")
  757. {
  758. Host lh(ClientSocket::getIP(NULL),0);
  759. char ipStr[64];
  760. lh.IPtoStr(ipStr);
  761. strcpy(buf,ipStr);
  762. }else if (var == "upgradeURL")
  763. strcpy(buf,servMgr->downloadURL);
  764. else if (var == "serverPort2")
  765. sprintf(buf,"%d",serverHost.port+1);
  766. else if (var.startsWith("allow."))
  767. {
  768. if (var == "allow.HTML1")
  769. strcpy(buf,(allowServer1&Servent::ALLOW_HTML)?"1":"0");
  770. else if (var == "allow.HTML2")
  771. strcpy(buf,(allowServer2&Servent::ALLOW_HTML)?"1":"0");
  772. else if (var == "allow.broadcasting1")
  773. strcpy(buf,(allowServer1&Servent::ALLOW_BROADCAST)?"1":"0");
  774. else if (var == "allow.broadcasting2")
  775. strcpy(buf,(allowServer2&Servent::ALLOW_BROADCAST)?"1":"0");
  776. else if (var == "allow.network1")
  777. strcpy(buf,(allowServer1&Servent::ALLOW_NETWORK)?"1":"0");
  778. else if (var == "allow.direct1")
  779. strcpy(buf,(allowServer1&Servent::ALLOW_DIRECT)?"1":"0");
  780. }else if (var.startsWith("auth."))
  781. {
  782. if (var == "auth.useCookies")
  783. strcpy(buf,(authType==AUTH_COOKIE)?"1":"0");
  784. else if (var == "auth.useHTTP")
  785. strcpy(buf,(authType==AUTH_HTTPBASIC)?"1":"0");
  786. else if (var == "auth.useSessionCookies")
  787. strcpy(buf,(cookieList.neverExpire==false)?"1":"0");
  788. }else if (var.startsWith("log."))
  789. {
  790. if (var == "log.debug")
  791. strcpy(buf,(showLog&(1<<LogBuffer::T_DEBUG))?"1":"0");
  792. else if (var == "log.errors")
  793. strcpy(buf,(showLog&(1<<LogBuffer::T_ERROR))?"1":"0");
  794. else if (var == "log.gnet")
  795. strcpy(buf,(showLog&(1<<LogBuffer::T_NETWORK))?"1":"0");
  796. else if (var == "log.channel")
  797. strcpy(buf,(showLog&(1<<LogBuffer::T_CHANNEL))?"1":"0");
  798. else
  799. return false;
  800. }else if (var == "test")
  801. {
  802. out.writeUTF8(0x304b);
  803. out.writeUTF8(0x304d);
  804. out.writeUTF8(0x304f);
  805. out.writeUTF8(0x3051);
  806. out.writeUTF8(0x3053);
  807. out.writeUTF8(0x0041);
  808. out.writeUTF8(0x0042);
  809. out.writeUTF8(0x0043);
  810. out.writeUTF8(0x0044);
  811. out.writeChar('a');
  812. out.writeChar('b');
  813. out.writeChar('c');
  814. out.writeChar('d');
  815. return true;
  816. }else
  817. return false;
  818. out.writeString(buf);
  819. return true;
  820. }