config.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. #pragma once
  2. #ifndef config_H_
  3. #define config_H_
  4. #include <string>
  5. #include <vector>
  6. #include <map>
  7. #include <list>
  8. #include <set>
  9. #include <stdlib.h>
  10. #include "unicode/uniFile.h"
  11. #include "stl/stringUtils.h"
  12. #include "threading/thread.h"
  13. #include "metrics.h"
  14. #define DEFAULT_SOURCE_STREAM 1
  15. #define DEFAULT_CLIENT_STREAM_ID 1
  16. #define DEFAULT_YP_ADDRESS "yp.shoutcast.com"
  17. #ifdef _WIN32
  18. #define DEFAULT_LOG "%temp%\\sc_serv.log"
  19. #define DEFAULT_LOGW L"%temp%\\sc_serv.log"
  20. #else
  21. #define DEFAULT_LOG "/tmp/sc_serv.log"
  22. #endif
  23. #define DEFAULT_FLASH_POLICY_FILE "crossdomain.xml"
  24. /*
  25. Each option has a map associated with a member. Let's take an option called foobar
  26. std::map<size_t,int> m_foobar;
  27. For single options (non-multi options) the map only has a single element. We use a map
  28. so we can treat all options, multi or not, in the same fashion
  29. The value of the option is assigned via the assign_<name> method. subIndex is only used
  30. for multi options (zero based). The value is always passed as a string and is converted
  31. automatically internally
  32. inline void assign_foobar(int subIndex,const uniString::utf8 &value)
  33. The value of the option is retrieved as a string via the fetch_<name> method. The value
  34. is fetched as a native type via native_fetch_<name> method. subIndex is used to select a
  35. particular entry in a multi option. It's ignored for regular options
  36. uniString::utf8 fetch_foobar(int subIndex)
  37. int native_fetch_foobar(int subIndex)
  38. A shorthand is provided via the _<name> method. It returns the same value as native_fetch_<name>
  39. const int _foobar()
  40. The number of elements for the option is returned by the count_<name> method. For single options
  41. this is always one
  42. size_t count_foobar()
  43. The multi_<name> method returns true if the option is a multi option
  44. bool multi_foobar()
  45. The def_<name> method returns the default value for the option as a string
  46. utf8 def_foobar()
  47. All the proceeding options are private, and not protected by a mutex.
  48. There are two public methods for accessing methods that provide mutex
  49. protection. The value of the options is <name>() and the default value
  50. is provided by <name>_Default()
  51. const int foobar()
  52. const int foobar_Default()
  53. All of this is created automatically via the OPT and OPT_MULTI macros below
  54. In the optMap table we associated all these functions with the actual name of the option
  55. as it appears in the config file. In addition there is a change function associated with
  56. each option that is fired when the option is changed.
  57. */
  58. /////////////////////////////////////////////////////////////////////////////////////
  59. ///////// crazy macros to provide uniform assign/fetch functions for each option
  60. /*
  61. Create a single option of type "tipe" with the name "name" and a default value of "def"
  62. */
  63. #define OPT(tipe,name,def)\
  64. private:\
  65. std::map<size_t,tipe> m_##name;\
  66. inline void assign_##name(const uniString::utf8 &value, const size_t subIndex = DEFAULT_CLIENT_STREAM_ID) throw() { assignMulti(m_##name, subIndex, value); }\
  67. uniString::utf8 fetch_##name(const size_t subIndex = DEFAULT_CLIENT_STREAM_ID, size_t *fetchByPos = 0) const throw() { return revert(fetchMulti(m_##name, subIndex, def, fetchByPos)); }\
  68. tipe native_fetch_##name(const size_t subIndex = DEFAULT_CLIENT_STREAM_ID, size_t *fetchByPos = 0) const throw() { return fetchMulti(m_##name, subIndex, def, fetchByPos); }\
  69. const tipe _##name() const throw() { return fetchMulti(m_##name, DEFAULT_CLIENT_STREAM_ID, def, 0); }\
  70. size_t count_##name() const throw() { return 1; }\
  71. bool multi_##name() const throw() { return false; }\
  72. uniString::utf8 def_##name() const throw() { return revert(def); }\
  73. public:\
  74. const tipe name() const throw() { return fetchMulti(m_##name, DEFAULT_CLIENT_STREAM_ID, def, 0); }\
  75. const tipe name##_Default() const throw() { return def; }
  76. // for options that can have multiple instances (like encoders and broadcast points)
  77. /*
  78. The option has the type "tipe" with the name "name" and a default value of "def"
  79. */
  80. #define OPT_MULTI(tipe,name,def)\
  81. private:\
  82. std::map<size_t, tipe> m_##name;\
  83. inline void assign_##name(const uniString::utf8 &value, const size_t subIndex) throw() { assignMulti(m_##name, subIndex, value); }\
  84. inline void native_assign_##name(const size_t subIndex, const tipe &value) throw() { native_assignMulti(m_##name, subIndex, value); }\
  85. uniString::utf8 fetch_##name(const size_t subIndex, size_t *fetchByPos = 0) const throw() { return revert(fetchMulti(m_##name, subIndex, def, fetchByPos)); }\
  86. tipe native_fetch_##name(const size_t subIndex) const throw() { return fetchMulti(m_##name, subIndex, def, 0); }\
  87. const tipe _##name(const std::vector<tipe>::size_type i) const throw() { return fetchMulti(m_##name, i, def, 0); }\
  88. bool multi_##name() const throw() { return true; }\
  89. uniString::utf8 def_##name() const throw() { return revert(def); }\
  90. public:\
  91. const bool read_##name(const size_t subIndex) const throw() { return (m_##name.find(subIndex) != m_##name.end()); }\
  92. void unread_##name(const size_t subIndex) { native_assignMulti(m_##name, subIndex, name##_Default()); }\
  93. const tipe name(const size_t subIndex) const throw() { return fetchMulti(m_##name, subIndex, def, 0); }\
  94. size_t count_##name() const throw() { return m_##name.size(); }\
  95. const std::map<size_t, tipe>& name##_map() const { return m_##name; } \
  96. const tipe name##_Default() const throw() { return def; }
  97. //////////////////////////////////////////////////////////////////////////////////////
  98. //////////////////////////////////////////////////////////////////////////////////////
  99. // global configuration
  100. class config
  101. {
  102. public:
  103. // stream specifications from config file.
  104. #pragma pack(push, 1)
  105. struct streamConfig
  106. {
  107. #pragma pack(push, 1)
  108. class urlObj
  109. {
  110. private:
  111. uniString::utf8 m_url;
  112. uniString::utf8 m_server;
  113. uniString::utf8 m_path;
  114. u_short m_port;
  115. static uniString::utf8 parse(const uniString::utf8 &url, uniString::utf8 &server,
  116. u_short &port, uniString::utf8 &path) throw(std::exception);
  117. public:
  118. explicit urlObj(const uniString::utf8 &url) throw(std::exception)
  119. {
  120. if (!url.empty())
  121. {
  122. set(url);
  123. }
  124. else
  125. {
  126. clear();
  127. }
  128. }
  129. urlObj& operator=(const uniString::utf8 &url) throw(std::exception)
  130. {
  131. set(url);
  132. return *this;
  133. }
  134. const uniString::utf8 &url() const throw() { return m_url; }
  135. const uniString::utf8 &server() const throw() { return m_server; }
  136. const uniString::utf8 &path() const throw() { return m_path; }
  137. const u_short port() const throw() { return m_port; }
  138. bool isSet() const throw() { return !m_url.empty(); }
  139. void set(const uniString::utf8 &url) throw(std::exception)
  140. {
  141. m_url = parse(url, m_server, m_port, m_path);
  142. }
  143. void clear() throw()
  144. {
  145. m_url.clear();
  146. m_port = 0;
  147. }
  148. };
  149. #pragma pack(pop)
  150. uniString::utf8 m_authHash;
  151. uniString::utf8 m_urlPath; // url that clients use to connect
  152. uniString::utf8 m_adminPassword; // per stream admin password
  153. uniString::utf8 m_password; // per stream source password
  154. uniString::utf8 m_publicServer; // per stream source public flag
  155. size_t m_streamID;
  156. int m_maxStreamUser; // per stream user limit
  157. int m_maxStreamBitrate; // per stream max bitrate limit
  158. int m_minStreamBitrate; // per stream min bitrate limit
  159. urlObj m_relayUrl; // if this is a relay, then this is set to the source url
  160. urlObj m_backupUrl; // if there is a backup, then this is set to the backup url
  161. bool m_allowRelay; // per stream relay allowed flag
  162. bool m_allowPublicRelay; // per stream relay public flag
  163. streamConfig() throw() : m_streamID(DEFAULT_CLIENT_STREAM_ID), m_maxStreamUser(0),
  164. m_maxStreamBitrate(0), m_minStreamBitrate(0),
  165. m_relayUrl((uniString::utf8)""), m_backupUrl((uniString::utf8)""),
  166. m_allowRelay(true), m_allowPublicRelay(true) {}
  167. streamConfig(const size_t id, const uniString::utf8 &authHash, const uniString::utf8 &url,
  168. const uniString::utf8 &relayUrl, const uniString::utf8 &backupUrl,
  169. const int maxStreamUser, const int maxStreamBitrate, const int minStreamBitrate,
  170. const uniString::utf8 &adminPassword, const uniString::utf8 &password,
  171. const uniString::utf8 &publicServer, const bool allowRelay,
  172. const bool allowPublicRelay) throw(std::exception)
  173. : m_authHash(authHash), m_urlPath(url), m_adminPassword(adminPassword), m_password(password),
  174. m_publicServer(publicServer), m_streamID(id), m_maxStreamUser(maxStreamUser),
  175. m_maxStreamBitrate(maxStreamBitrate), m_minStreamBitrate(minStreamBitrate), m_relayUrl(relayUrl),
  176. m_backupUrl(backupUrl), m_allowRelay(allowRelay), m_allowPublicRelay(allowPublicRelay) {}
  177. };
  178. #pragma pack(pop)
  179. ///////////////////////////////////////////////////////////////////////
  180. ///// functions to convert types to and from unicode strings
  181. template<typename T> inline static void convert(const uniString::utf8 &v,T &r) throw() { r = v; }
  182. #ifdef _WIN64
  183. inline static void convert(const uniString::utf8 &v,size_t &r) throw() { r = atoi((const char *)v.c_str()); }
  184. #endif
  185. inline static void convert(const uniString::utf8 &v, int &r) throw() { r = atoi((const char *)v.c_str()); }
  186. inline static void convert(const uniString::utf8 &v, unsigned int &r) throw() { r = atoi((const char *)v.c_str()); }
  187. inline static void convert(const uniString::utf8 &v, unsigned long &r) throw() { r = atol((const char *)v.c_str()); }
  188. inline static void convert(const uniString::utf8 &v, unsigned short &r) throw() { r = (unsigned short)atoi((const char *)v.c_str()); }
  189. inline static void convert(const uniString::utf8 &v, short &r) throw() { r = (short)atoi((const char *)v.c_str()); }
  190. inline static void convert(const uniString::utf8 &v, bool &r) throw() { r = (atoi((const char *)v.c_str()) ? true : false); }
  191. inline static void convert(const uniString::utf8 &v, double &r) throw() { r = atof((const char *)v.c_str()); }
  192. template<typename T> inline static uniString::utf8 revert(const T &r) throw() { return r; }
  193. #ifdef _WIN64
  194. inline static uniString::utf8 revert(size_t r) throw() { return stringUtil::tos(r); }
  195. #endif
  196. inline static uniString::utf8 revert(int r) throw() { return stringUtil::tos(r); }
  197. inline static uniString::utf8 revert(unsigned int r) throw() { return stringUtil::tos(r); }
  198. inline static uniString::utf8 revert(unsigned long r) throw() { return stringUtil::tos(r); }
  199. inline static uniString::utf8 revert(unsigned short r) throw() { return stringUtil::tos(r); }
  200. inline static uniString::utf8 revert(short r) throw() { return stringUtil::tos(r); }
  201. inline static uniString::utf8 revert(bool r) throw() { return (r ? "1" : "0"); }
  202. inline static uniString::utf8 revert(double r) throw() { return stringUtil::tos(r); }
  203. ////////////////////////////////////////////////////////////////////////
  204. ////////////////////////////////////////////////////////////////////////
  205. private:
  206. mutable AOL_namespace::mutex m_lock; // api may write to config, so we need a lock
  207. ////////////////////////////////////////////////////////////////////////////////////////////
  208. //// tables and functions so we can read and write options in a generic manner based
  209. /// on the names that are used in the config file
  210. typedef void (config::*assignFunc_t)(const uniString::utf8 &, const size_t subIndex);
  211. typedef uniString::utf8 (config::*fetchFunc_t)(const size_t subIndex, size_t *fetchByPos) const;
  212. typedef size_t (config::*countFunc_t)() const;
  213. typedef bool (config::*multiFunc_t)() const;
  214. typedef uniString::utf8 (config::*defaultFunc_t)() const;
  215. struct accessor_t
  216. {
  217. assignFunc_t m_assignFunc;
  218. fetchFunc_t m_fetchFunc;
  219. countFunc_t m_countFunc;
  220. multiFunc_t m_multiFunc;
  221. defaultFunc_t m_defaultFunc;
  222. accessor_t(assignFunc_t af, fetchFunc_t ff, countFunc_t cf, multiFunc_t mf, defaultFunc_t df) throw()
  223. : m_assignFunc(af), m_fetchFunc(ff), m_countFunc(cf), m_multiFunc(mf), m_defaultFunc(df) {}
  224. accessor_t() throw() : m_assignFunc(0), m_fetchFunc(0), m_countFunc(0), m_multiFunc(0), m_defaultFunc(0) {}
  225. };
  226. public:
  227. typedef std::map<uniString::utf8,accessor_t> optMap_t;
  228. //////////////////////////////////////////////////////////////////////////////////////
  229. //////////////////////////////////////////////////////////////////////////////////////
  230. // takes an option map (container) and returns the value at the index (i) if it exists,
  231. // otherwise it returns the default value (defaultValue). Value returned as native type
  232. template<typename T,typename D>
  233. static T fetchMulti(const std::map<size_t,T> &container, const typename std::vector<T>::size_type &subIndex,
  234. const D defaultValue, size_t *fetchByPos) throw()
  235. {
  236. if (!fetchByPos)
  237. {
  238. typename std::map<size_t,T>::const_iterator i = container.find(subIndex);
  239. if (i != container.end())
  240. {
  241. return (*i).second;
  242. }
  243. }
  244. else
  245. {
  246. // there's cases where we need to get the value
  247. // effectively by it's position in the map so
  248. // for the moment we'll just look through (bad
  249. // for speed but it's not a commonly used mode).
  250. typename std::vector<T>::size_type pos = 0;
  251. for (typename std::map<size_t,T>::const_iterator i = container.begin(); i != container.end(); ++i, pos++)
  252. {
  253. if (pos == subIndex)
  254. {
  255. *fetchByPos = (*i).first;
  256. return (*i).second;
  257. }
  258. }
  259. }
  260. return defaultValue;
  261. }
  262. private:
  263. // assign map index. Expand with default value as needed. Value is specified as a string and converted as needed
  264. template<typename T>
  265. static void assignMulti(std::map<size_t,T> &container, const typename std::vector<T>::size_type subIndex, const uniString::utf8 &value) throw()
  266. {
  267. T vtmp;
  268. convert(value, vtmp);
  269. container[subIndex] = vtmp;
  270. }
  271. // same as assignMulti, but you can provide the native type instead of a string
  272. template<typename T>
  273. static void native_assignMulti(std::map<size_t,T> &container, const typename std::vector<T>::size_type subIndex, const T &value) throw()
  274. {
  275. container[subIndex] = value;
  276. }
  277. /////////////////////////////////////////////////////////////////////////////////
  278. ///////////////////////////////////////////////////////////////////////////////////
  279. // radionomy metrics
  280. OPT(bool,adMetricsDebug,false)
  281. OPT(size_t,metricsMaxQueue,80000)
  282. OPT(bool,authDebug,false)
  283. public:
  284. friend void metrics::metrics_apply(config &conf);
  285. private:
  286. optMap_t m_optMap;
  287. // we can't log during startup because the loggers don't exist
  288. std::vector<uniString::utf8> m_deferredWarnLogMessages; // log warning messages from startup
  289. std::vector<uniString::utf8> m_deferredErrorLogMessages; // log error messages from startup
  290. // deferred options are those that weren't set because they can't take effect immediately
  291. // they are used when writing out the new config file.
  292. std::map<uniString::utf8,uniString::utf8> m_deferredOptions;
  293. OPT(size_t,configRewrite,0)
  294. OPT(uniFile::filenameType,confFile,"")
  295. OPT(uniFile::filenameType,logFile,DEFAULT_LOG) // file for logging
  296. OPT(uniFile::filenameType,realLogFile,DEFAULT_LOG) // file for logging
  297. OPT(bool,screenLog,true) // log to screen
  298. OPT(bool,log,true) // do I log?
  299. OPT(int,logRotates,5) // hwo many backups to keep when doing a log rotate?
  300. OPT(bool,logArchive,false) // backup rotated files which would otherwise be deleted
  301. OPT(int,rotateInterval,86400) // interval between log file rotations (24 hours)
  302. // if set to 0 then we won't rotate any of the files
  303. OPT(int,portBase,8000) // listen port
  304. OPT(int,publicPort,-1) // listen port for firehose - workaround for firehose hosts running on port 8000
  305. // but need to effectively be seen as bound to port 80 - allowing all to work ok
  306. OPT(int,portLegacy,-1) // legacy port override/disable
  307. OPT(uniString::utf8,alternatePorts,(uniString::utf8)"") // alternate port(s) for client only connections - comma separated string
  308. OPT(bool,nameLookups,false) // do internet reverse lookups
  309. OPT(uniString::utf8,sslCertificateFile,"");
  310. OPT(uniString::utf8,sslCertificateKeyFile,"");
  311. OPT(int,autoDumpTime,30) // how long before an idle connection is dumped (in seconds). Zero means no timeout
  312. OPT(int,maxHeaderLineSize,4096) // maximum size of an HTTP header line. Default is pretty arbitrary right now
  313. // but should be at least as big as a u-vox packet, since we have to anaylize
  314. // initial data bytes to determine protocol and type of connectee (source or client)
  315. OPT(int,maxHeaderLineCount,100) // max headers lines in HTTP style exchange
  316. OPT(uniString::utf8,password,(uniString::utf8)""); // password for broadcaster to connect
  317. OPT(uniString::utf8,adminPassword,(uniString::utf8)""); // administrator password
  318. // buffer configuration options
  319. OPT(int,bufferType,1) // 0 - fixed, 1 - adaptive
  320. OPT(size_t,fixedBufferSize,524288) // size of buffer if fixed (gives ~32 seconds ~ 128kbps, 44.1kHz)
  321. OPT(double,adaptiveBufferSize,16) // size of adaptive buffer in seconds
  322. OPT(size_t,bufferHardLimit,16777216) // no more than this give or take a factor of two
  323. OPT(unsigned short,metaInterval,16384) // metadata interval for shoutcast 1
  324. OPT_MULTI(unsigned short,stream_metaInterval,16384) // per-stream override
  325. // special intro and backup files
  326. OPT(uniFile::filenameType,introFile,"")
  327. OPT(uniFile::filenameType,backupFile,"")
  328. OPT(uniFile::filenameType,backupTitle,"")
  329. OPT(int,backupLoop,0)
  330. OPT(int,maxSpecialFileSize,30000000)
  331. OPT(int,adTestFileLoop,1)
  332. OPT(uniFile::filenameType,adTestFile,"")
  333. OPT(uniFile::filenameType,adTestFile2,"")
  334. OPT(uniFile::filenameType,adTestFile3,"")
  335. OPT(uniFile::filenameType,adTestFile4,"")
  336. OPT(uniFile::filenameType,artworkFile,"")
  337. std::map<size_t, uniString::utf8> m_artworkBody;
  338. OPT(uniString::utf8,uvoxCipherKey,uniString::utf8("foobar"))
  339. // w3c logs
  340. OPT(bool,w3cEnable,true)
  341. OPT(uniString::utf8,w3cLog,uniString::utf8("sc_w3c.log"))
  342. OPT(uniString::utf8,pidFile,uniString::utf8("sc_serv_$.pid"))
  343. // relaying
  344. OPT(bool,allowRelay,true) // can other servers relay us. Based on Shoutcast user agent, not reliable
  345. OPT(bool,allowPublicRelay,true) // relays can list themselves in yp
  346. OPT(short,maxHTTPRedirects,5) // max times we can redirect (http 3xx)
  347. OPT(int,relayReconnectTime,5) // seconds to reconnect on relay failure
  348. OPT(int,relayConnectRetries,0) // number of times we retry a relay request before throwing it away
  349. // which if set as zero will keep retrying (excluding bitrate blocks)
  350. ////// stream configs
  351. OPT_MULTI(size_t,stream_ID,DEFAULT_CLIENT_STREAM_ID)
  352. OPT_MULTI(uniString::utf8,stream_authHash,(uniString::utf8)"")
  353. OPT_MULTI(uniString::utf8,stream_path,(uniString::utf8)"")
  354. OPT_MULTI(uniString::utf8,stream_relayURL,(uniString::utf8)"")
  355. OPT_MULTI(uniString::utf8,stream_backupURL,(uniString::utf8)"")
  356. OPT_MULTI(uniString::utf8,stream_password,(uniString::utf8)"")
  357. OPT_MULTI(uniString::utf8,stream_adminPassword,(uniString::utf8)"")
  358. OPT_MULTI(uniString::utf8,stream_publicServer,(uniString::utf8)"") // if "always" or "never" overrides public flag from source
  359. OPT_MULTI(bool,stream_allowRelay,true) // can other servers relay us. Based on Shoutcast user agent, not reliable
  360. OPT_MULTI(bool,stream_allowPublicRelay,true) // relays can list themselves in yp
  361. OPT_MULTI(int,stream_maxUser,0) // if set to a value greater than zero then we have per stream limits
  362. OPT_MULTI(int,stream_maxBitrate,0) // if set to a value greater than zero then we have per stream limits
  363. OPT_MULTI(int,stream_minBitrate,0) // if set to a value greater than zero then we have per stream limits
  364. OPT_MULTI(bool,stream_ripOnly,false) // only addrs in rip file may connect
  365. OPT_MULTI(int,stream_autoDumpTime,30) // how long before an idle connection is dumped (in seconds). Zero means no timeout
  366. OPT_MULTI(int,stream_autoDumpSourceTime,7) // how long before an idle source connection is dumped (in seconds). Zero means no timeout
  367. OPT_MULTI(bool,stream_autoDumpUsers,false) // if true, then users are dumped if source disconnects
  368. OPT_MULTI(size_t,stream_listenerTime,0) // max time in minutes you can listen. 0 means no limit
  369. OPT_MULTI(int,stream_songHistory,10) // max song history to preserve
  370. OPT_MULTI(uniString::utf8,stream_uvoxCipherKey,(uniString::utf8)"")
  371. OPT_MULTI(uniFile::filenameType,stream_logFile,""); // file for per mount logging
  372. OPT_MULTI(int,stream_adTestFileLoop,1)
  373. OPT_MULTI(uniFile::filenameType,stream_adTestFile,"")
  374. OPT_MULTI(uniFile::filenameType,stream_adTestFile2,"")
  375. OPT_MULTI(uniFile::filenameType,stream_adTestFile3,"")
  376. OPT_MULTI(uniFile::filenameType,stream_adTestFile4,"")
  377. OPT_MULTI(uniFile::filenameType,stream_introFile,"")
  378. OPT_MULTI(uniFile::filenameType,stream_backupFile,"")
  379. OPT_MULTI(uniFile::filenameType,stream_backupTitle,"")
  380. OPT_MULTI(int,stream_backupLoop,0)
  381. OPT_MULTI(int,stream_rateLimitWait,0)
  382. OPT_MULTI(uniFile::filenameType,stream_artworkFile,"")
  383. OPT_MULTI(uniFile::filenameType,stream_banFile,"")
  384. OPT_MULTI(uniFile::filenameType,stream_ripFile,"")
  385. OPT_MULTI(uniFile::filenameType,stream_agentFile,"")
  386. OPT_MULTI(uniString::utf8,stream_w3cLog,(uniString::utf8)"")
  387. OPT_MULTI(uniString::utf8,stream_hideStats,(uniString::utf8)"") // hide /stats & /statistics as well as /index and /played public facing pages
  388. OPT_MULTI(uniString::utf8,stream_redirectUrl,(uniString::utf8)"") // used with hideStats=all or if the stream version isn't specified
  389. OPT_MULTI(uniString::utf8,stream_movedUrl,(uniString::utf8)"") // used to redirect a deemed dead stream (just in case)
  390. OPT(bool,requireStreamConfigs,false) // if true, then sources can only connect if stream configs have been defined
  391. OPT(uniString::utf8,userId,"")
  392. OPT(uniString::utf8,licenceId,"")
  393. // flash policy
  394. OPT(int,flashPolicyServerPort,-1) // listen on port 843 for flash policy server request
  395. OPT(uniFile::filenameType,flashPolicyFile,DEFAULT_FLASH_POLICY_FILE)
  396. uniString::utf8 m_crossdomainStr; // used to hold a cached copy of the crossdomain.xml file
  397. uniString::utf8 m_crossdomainStrGZ; // used to hold a cached copy of the gzipped crossdomain.xml file
  398. uniString::utf8 m_shoutcastSWFStr; // used to hold a cached copy of the shoutcast.swf file
  399. uniString::utf8 m_shoutcastSWFStrGZ; // used to hold a cached copy of the gzipped shoutcast.swf file
  400. uniString::utf8 m_usedAlternatePorts; // used to hold a copy of the valid alternate ports in use
  401. ////// yp
  402. OPT(int,ypTimeout,30) // yp timeout interval for requests
  403. OPT(uniString::utf8,ypAddr,DEFAULT_YP_ADDRESS)
  404. OPT(int,ypPort,80)
  405. OPT(uniString::utf8,ypPath,"/yp2")
  406. OPT(int,ypMaxRetries,10) // number of times we retry a yp request before throwing it away
  407. OPT(int,ypReportInterval,5 * 60) // never touch any slower than this
  408. OPT(int,ypMinReportInterval,10) // never touch any faster than this
  409. OPT(uniString::utf8,publicServer,"default") // if "always" or "never" overrides public flag from source
  410. //// cdn behaviour
  411. OPT(uniString::utf8,cdn,"") // if 'on' or 'always' then we enable all of the cdn modes (including YP pings for private streams)
  412. // but use it to determine opt-in (via 'on') or opt-out (via 'always')
  413. OPT_MULTI(int,cdn_master,-1) // this and the option below is used to control the behaviour of things
  414. OPT_MULTI(int,cdn_slave,-1)
  415. //// stats
  416. OPT(int,maxUser,512) // max clients
  417. OPT(int,minBitrate,0) // min bitrate of source connections - if zero / not set then there is no limit
  418. OPT(int,maxBitrate,0) // max bitrate of source connections - if zero / not set then there is no limit
  419. OPT(uniString::utf8,hideStats,"") // hide /stats & /statistics as well as /index and /played public facing pages
  420. OPT(uniString::utf8,redirectUrl,"") // used with hideStats=all or if the stream version isn't specified
  421. /// client behaviour
  422. OPT(size_t,listenerTime,0) // max time in minutes you can listen. 0 means no limit
  423. OPT(bool,autoDumpUsers,false) // if true, then users are dumped if source disconnects
  424. OPT(uniString::utf8,srcIP,"") // bind addr for sources
  425. OPT(uniString::utf8,destIP,"") // bind addr for clients
  426. OPT(uniString::utf8,publicIP,"") // public address to use for the YP listing if the bind addr is not appropriate
  427. OPT(uniString::utf8,titleFormat,"") // modifies icy-name
  428. OPT(uniString::utf8,urlFormat,"") // modifies icy-url
  429. //// banning
  430. OPT(uniFile::filenameType,banFile,"sc_serv.ban")
  431. OPT(bool,saveBanListOnExit,true) // save on exiting
  432. //// rip
  433. OPT(uniFile::filenameType,ripFile,"sc_serv.rip")
  434. OPT(bool,saveRipListOnExit,true) // save on exiting
  435. OPT(bool,ripOnly,false) // only addrs in rip file may connect
  436. OPT(uniFile::filenameType,adminFile,"sc_serv.admin")
  437. /// agent
  438. OPT(uniFile::filenameType,agentFile,"sc_serv.agent")
  439. OPT(bool,saveAgentListOnExit,true) // save on exiting
  440. OPT(bool,blockEmptyUserAgent,false) // if true, block the client connection if there is no user agent specified
  441. //// debugging
  442. OPT(bool,webClientDebug,false)
  443. OPT(bool,yp2Debug,false)
  444. OPT(bool,shoutcastSourceDebug,false)
  445. OPT(bool,uvox2SourceDebug,false)
  446. OPT(bool,HTTPSourceDebug,false)
  447. OPT(bool,streamDataDebug,false)
  448. OPT(bool,microServerDebug,false)
  449. OPT(bool,httpStyleDebug,false)
  450. OPT(bool,shoutcast1ClientDebug,false)
  451. OPT(bool,shoutcast2ClientDebug,false)
  452. OPT(bool,HTTPClientDebug,false)
  453. OPT(bool,flvClientDebug,false)
  454. OPT(bool,m4aClientDebug,false)
  455. OPT(bool,relayDebug,false)
  456. OPT(bool,relayShoutcastDebug,false)
  457. OPT(bool,relayUvoxDebug,false)
  458. OPT(bool,statsDebug,false)
  459. OPT(bool,threadRunnerDebug,false)
  460. OPT(bool,logClients,true)
  461. OPT(int,songHistory,20) // max song history to preserve
  462. /// misc nonsense
  463. OPT(uniString::utf8,unique,"$") // subsitution string for file names to mimic old sc_serv conf file behaviour
  464. OPT(uniString::utf8,include,"") // include file placeholder
  465. OPT(int,cpuCount,0) // cpu usage. zero is default
  466. OPT(bool,clacks,true) // need i say more...?
  467. OPT(bool,startInactive,false) // used to not start the relays on startup
  468. OPT(bool,rateLimit,true); // if we do frame rate limiting or not
  469. OPT(int,rateLimitWait,5); // if we do frame rate limiting, how many seconds before we enforce it fully
  470. OPT(bool,useXFF,true); // if we use XFF (if available) for the listener address (and related actions)
  471. OPT(bool,forceShortSends,false);// used for debugging streaming issues by introducing forced delays into sends
  472. OPT(bool,adminNoWrap,false); // used for defaulting the admin listener page mode for wrapping or not
  473. // wrapping the listener output list which might be handy for some users
  474. // used for customising the css of the index.html and admin pages
  475. OPT(uniFile::filenameType,adminCSSFile,"v2")
  476. uniString::utf8 m_styleCustomStr; // used to hold a cached copy of the custom css file
  477. uniString::utf8 m_styleCustomStrGZ; // used to hold a cached copy of the gzipped custom css file
  478. uniString::utf8 m_styleCustomHeader; // used to hold a cached copy of the gzipped custom css file
  479. uniString::utf8 m_styleCustomHeaderGZ; // used to hold a cached copy of the gzipped custom css file
  480. time_t m_styleCustomHeaderTime; // used to control the cache handling
  481. OPT(uniFile::filenameType,faviconFile,"")
  482. OPT(uniFile::filenameType,faviconFileMimeType,"image/x-icon")
  483. uniString::utf8 m_faviconBody;
  484. uniString::utf8 m_faviconHeader;
  485. uniString::utf8 m_faviconBodyGZ; // gzipped version
  486. uniString::utf8 m_faviconHeaderGZ; // gzipped version
  487. time_t m_favIconTime; // used to control the cache handling
  488. // used for returning robots.txt
  489. OPT(uniFile::filenameType,robotstxtFile,"")
  490. uniString::utf8 m_robotsTxtBody;
  491. uniString::utf8 m_robotsTxtHeader;
  492. uniString::utf8 m_robotsTxtBodyGZ; // gzipped version
  493. uniString::utf8 m_robotsTxtHeaderGZ; // gzipped version
  494. uniString::utf8 m_certPath;
  495. uniString::utf8 m_certFileBody;
  496. const bool _load(const uniFile::filenameType &file, const uniString::utf8 &uniqueStr, const bool parent) throw();
  497. int promptConfigFile() throw();
  498. bool editConfigFileEntry(size_t sid, const uniFile::filenameType &filename,
  499. const uniString::utf8 &authhash, const uniString::utf8 &param,
  500. bool add, bool &handled, bool &idHandled, bool parent) throw();
  501. // used for legacy handling of the relayport and relayserver options to sid=1
  502. uniString::utf8 m_legacyRelayPort;
  503. uniString::utf8 m_legacyRelayServer;
  504. streamConfig& getPerStreamConfig(streamConfig& stream, const size_t sid, const bool useParent = true);
  505. public:
  506. config() throw();
  507. ~config() throw();
  508. static std::string logSectionName();
  509. uniString::utf8 getCrossDomainFile(const bool compressed) throw();
  510. uniString::utf8 getIndexCSS(const bool compressed) throw();
  511. uniString::utf8 getShoutcastSWF(const bool compressed) throw();
  512. const uniString::utf8 getStreamRedirectURL(const size_t streamID, const bool isStats, const bool homeSet,
  513. const bool compress, const bool force = false) const throw();
  514. int getRateLimitWait(const size_t streamID) const throw();
  515. const int isBitrateDisallowed(const size_t streamID, const int bitrate, int &streamMinBitrate, int &streamMaxBitrate) const throw();
  516. unsigned short getMetaInterval(const size_t streamID) const throw();
  517. int getBackupLoop(const size_t streamID) const throw();
  518. size_t getSongHistorySize(const size_t streamID) const throw();
  519. const int getAutoDumpTime(const size_t streamID = DEFAULT_SOURCE_STREAM) const throw();
  520. const int getCPUCount() const throw();
  521. const std::vector<streamConfig> getRelayList();
  522. const std::vector<streamConfig> getBackupUrl(const size_t streamID) throw(std::exception);
  523. const uniString::utf8 getStreamHideStats(const size_t streamID) const;
  524. typedef std::map<size_t, config::streamConfig> streams_t;
  525. void getStreamConfigs(streams_t& streams, const bool useParent = true);
  526. const bool getStreamConfig(streamConfig& stream, const size_t streamID);
  527. // handle updating stream configs on the fly (as applicable)
  528. #define AUTH_HASH 0x1
  529. #define URL_PATH 0x2
  530. #define RELAY_URL 0x4
  531. #define MAX_USER 0x8
  532. #define SOURCE_PWD 0x10
  533. #define ADMIN_PWD 0x20
  534. #define PUBLIC_SRV 0x40
  535. #define ALLOW_RELAY 0x80
  536. #define ALLOW_PUBLIC_RELAY 0x100
  537. #define RIP_ONLY 0x200
  538. #define DUMP_TIME 0x400
  539. #define DUMP_USER 0x800
  540. #define LIST_TIME 0x1000
  541. #define SONG_HIST 0x2000
  542. #define CIPHER_KEY 0x4000
  543. #define INTRO_FILE 0x8000
  544. #define BACKUP_FILE 0x10000
  545. #define BAN_FILE 0x20000
  546. #define RIP_FILE 0x40000
  547. #define W3C_FILE 0x80000
  548. #define MAX_BITRATE 0x100000
  549. #define BACKUP_URL 0x200000
  550. #define HIDE_STATS 0x400000
  551. #define MOVED_URL 0x800000
  552. #define AGENT_FILE 0x1000000
  553. #define CDN_MASTER 0x2000000
  554. #define CDN_SLAVE 0x4000000
  555. #define ARTWORK_FILE 0x8000000
  556. #define BACKUP_LOOP 0x10000000
  557. #define BACKUP_TITLE 0x20000000
  558. #define MIN_BITRATE 0x40000000
  559. #define AD_TEST_FILE 0x80000000
  560. #define AD_TEST_FILE_LOOP 0x100000000ULL
  561. #define RATE_LIMIT_WAIT 0x200000000ULL
  562. #define METAINTERVAL 0x400000000ULL
  563. #define AD_TEST_FILE_2 0x800000000ULL
  564. #define AD_TEST_FILE_3 0x1000000000ULL
  565. #define AD_TEST_FILE_4 0x2000000000ULL
  566. void addStreamConfig(config &readConfig, config::streamConfig) throw(std::exception);
  567. __uint64 updateStreamConfig(config &readConfig, config::streamConfig update) throw(std::exception);
  568. void removeStreamConfig(config::streamConfig) throw(std::exception);
  569. // deals with configuring all of the per-stream passwords, etc
  570. static bool setupPasswords(const config::streams_t &) throw(std::exception);
  571. void setOption(uniString::utf8 key, uniString::utf8 value) throw(std::exception);
  572. bool load(const uniFile::filenameType &file, bool load = true) throw();
  573. bool rewriteConfigurationFile(bool minimal = true, bool messages = false, bool setup = false) const throw(std::exception); // throw on I/O error
  574. uniString::utf8 dumpConfigFile() throw();
  575. //////////////////////////////////////////////////////////////////////////////////////
  576. const std::vector<uniString::utf8>& deferredWarnLogMessages() const throw() { stackLock sml(m_lock); return m_deferredWarnLogMessages; }
  577. const std::vector<uniString::utf8>& deferredErrorLogMessages() const throw() { stackLock sml(m_lock); return m_deferredErrorLogMessages; }
  578. void clearDeferredWarnLogMessages() throw() { stackLock sml(m_lock); m_deferredWarnLogMessages.clear(); }
  579. void clearDeferredErrorLogMessages() throw() { stackLock sml(m_lock); m_deferredErrorLogMessages.clear(); }
  580. /////////// interface for service templates
  581. const std::vector<uniString::utf8> fromArgs(const std::vector<uniString::utf8> &cl) throw();
  582. bool getConsoleLogging() const throw();
  583. const uniFile::filenameType getFileLog() const throw();
  584. static uniString::utf8 getSystemLogConfigString() throw();
  585. static uniString::utf8 getVersionBuildStrings() throw();
  586. ////////////////////////////////////////////////////////////////////////////
  587. };
  588. #undef OPT
  589. #undef OPT_MULTI
  590. #endif