http-aux.h
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:13k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) Xerox Corporation 1998. All rights reserved.
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify it
  5.  * under the terms of the GNU General Public License as published by the
  6.  * Free Software Foundation; either version 2 of the License, or (at your
  7.  * option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful, but
  10.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  * General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License along
  15.  * with this program; if not, write to the Free Software Foundation, Inc.,
  16.  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17.  *
  18.  * Linking this file statically or dynamically with other modules is making
  19.  * a combined work based on this file.  Thus, the terms and conditions of
  20.  * the GNU General Public License cover the whole combination.
  21.  *
  22.  * In addition, as a special exception, the copyright holders of this file
  23.  * give you permission to combine this file with free software programs or
  24.  * libraries that are released under the GNU LGPL and with code included in
  25.  * the standard release of ns-2 under the Apache 2.0 license or under
  26.  * otherwise-compatible licenses with advertising requirements (or modified
  27.  * versions of such code, with unchanged license).  You may copy and
  28.  * distribute such a system following the terms of the GNU GPL for this
  29.  * file and the licenses of the other code concerned, provided that you
  30.  * include the source code of that other code when and as the GNU GPL
  31.  * requires distribution of source code.
  32.  *
  33.  * Note that people who make modified versions of this file are not
  34.  * obligated to grant this special exception for their modified versions;
  35.  * it is their choice whether to do so.  The GNU General Public License
  36.  * gives permission to release a modified version without this exception;
  37.  * this exception also makes it possible to release a modified version
  38.  * which carries forward this exception.
  39.  *
  40.  * $Header: /cvsroot/nsnam/ns-2/webcache/http-aux.h,v 1.17 2005/08/26 05:05:31 tomh Exp $
  41.  */
  42. //
  43. // Auxiliary classes for HTTP multicast invalidation proxy cache
  44. //
  45. #ifndef ns_http_aux_h
  46. #define ns_http_aux_h
  47. #include <tclcl.h>
  48. #include "random.h"
  49. #include "ns-process.h"
  50. #include "pagepool.h"
  51. #include "timer-handler.h"
  52. const int HTTP_HBEXPIRE_COUNT = 5; // How many lost HBs mean disconnection?
  53. const int HTTP_HBINTERVAL = 60;// Heartbeat intervals (seconds)
  54. const int HTTP_UPDATEINTERVAL = 5; // Delays to push/v1 (seconds)
  55. class HttpMInvalCache;
  56. // Used for caches to keep track of invalidations
  57. class InvalidationRec {
  58. public:
  59. InvalidationRec(const char *pid, double mtime, char updating = 0) {
  60. pg_ = new char[strlen(pid) + 1];
  61. strcpy(pg_, pid);
  62. mtime_ = mtime;
  63. scount_ = HTTP_HBEXPIRE_COUNT;
  64. updating_ = updating;
  65. next_ = 0, prev_ = 0;
  66. }
  67. virtual ~InvalidationRec() {
  68. delete []pg_;
  69. }
  70. const char* pg() const { return pg_; }
  71. double mtime() const { return mtime_; }
  72. char updating() const { return updating_; }
  73. int scount() const { return scount_; }
  74. InvalidationRec* next() { return next_; } 
  75. void reset(double mtime) {
  76. scount_ = HTTP_HBEXPIRE_COUNT;
  77. mtime_ = mtime;
  78. }
  79. int dec_scount() { return --scount_; }
  80. void set_updating() { updating_ = 1; }
  81. void clear_updating() { updating_ = 0; }
  82. void insert(InvalidationRec **head) {
  83. next_ = *head;
  84. if (next_ != 0)
  85. next_->prev_ = &next_;
  86. prev_ = head;
  87. *head = this;
  88. }
  89. void detach() {
  90. if (prev_ != 0)
  91. *prev_ = next_;
  92. if (next_ != 0)
  93. next_->prev_ = prev_;
  94. }
  95. friend class HttpMInvalCache;
  96. protected:
  97. char *pg_;
  98. double mtime_;
  99. char updating_; // 1 if an update is going to be sent soon
  100. int scount_; // Times that an invalidation needs to be multicast
  101. InvalidationRec *next_;
  102. InvalidationRec **prev_;
  103. };
  104. class HBTimer : public TimerHandler {
  105. public: 
  106. HBTimer(HttpMInvalCache *a, double interval) : TimerHandler() { 
  107. a_ = a, interval_ = interval; 
  108. }
  109. void set_interval(double interval) { interval_ = interval; }
  110. double get_interval() const { return interval_; }
  111. double next_interval() {
  112. return interval_ * (1 + Random::uniform(-0.1,0.1));
  113. }
  114. void sched() { TimerHandler::sched(interval_); }
  115. void resched() {
  116. TimerHandler::resched(next_interval());
  117. }
  118. protected: 
  119. virtual void expire(Event *e);
  120. virtual void handle(Event *e) {
  121. TimerHandler::handle(e);
  122. resched();
  123. }
  124. HttpMInvalCache *a_;
  125. double interval_;
  126. };
  127. class PushTimer : public TimerHandler {
  128. public:
  129. PushTimer(HttpMInvalCache *a, double itv) : 
  130. TimerHandler(), a_(a), interval_(itv) {}
  131. void set_interval(double itv) { interval_ = itv; } 
  132. double get_interval() const { return interval_; }
  133. void sched() {
  134. TimerHandler::sched(interval_);
  135. }
  136. protected:
  137. virtual void expire(Event *e);
  138. HttpMInvalCache *a_;
  139. double interval_;
  140. };
  141. class LivenessTimer : public TimerHandler {
  142. public:
  143. LivenessTimer(HttpMInvalCache *a, double itv, int nbr) :
  144. TimerHandler(), a_(a), nbr_(nbr), interval_(itv) {}
  145. void sched() { TimerHandler::sched(interval_); }
  146. void resched() { TimerHandler::resched(interval_); }
  147. protected:
  148. virtual void expire(Event *e);
  149. HttpMInvalCache *a_; // The cache to be alerted
  150. int nbr_; // Neighbor cache id
  151. double interval_;
  152. };
  153. // XXX ADU defined in app-connector.h
  154. const int HTTPDATA_COST = 8;
  155. // User-level packets
  156. class HttpData : public AppData {
  157. private:
  158. int id_; // ID of the sender
  159. public:
  160. HttpData() : AppData(HTTP_DATA) {}
  161. HttpData(AppDataType t, int d) : AppData(t) { id_ = d; }
  162. HttpData(HttpData& d) : AppData(d) { id_ = d.id_; }
  163. inline int& id() { return id_; }
  164. virtual int size() const { return sizeof(HttpData); }
  165. virtual int cost() const { return HTTPDATA_COST; }
  166. virtual AppData* copy() { return (new HttpData(*this)); }
  167. };
  168. // HTTP data during normal request and response: containing a tcl command
  169. class HttpNormalData : public HttpData {
  170. private: 
  171. char *str_;
  172. int strlen_;
  173. int cost_;
  174. public:
  175. // XXX Whoever sends data should allocate memory to store the string.
  176. // Whoever receives this object should delete it to free the string.
  177. HttpNormalData(int id, int cost, const char *str) : 
  178. HttpData(HTTP_NORMAL, id) {
  179. if ((str == NULL) || (*str == 0))
  180. strlen_ = 0;
  181. else
  182. strlen_ = strlen(str) + 1;
  183. if (strlen_ > 0) {
  184. str_ = new char[strlen_];
  185. strcpy(str_, str);
  186. } else
  187. str_ = NULL;
  188. cost_ = cost;
  189. }
  190. HttpNormalData(HttpNormalData& d) : HttpData(d) {
  191. cost_ = d.cost_;
  192. strlen_ = d.strlen_;
  193. if (strlen_ > 0) {
  194. str_ = new char[strlen_];
  195. strcpy(str_, d.str_);
  196. } else
  197. str_ = NULL;
  198. }
  199. virtual ~HttpNormalData() {
  200. if (str_ != NULL)
  201. delete []str_;
  202. }
  203. virtual int size() const {
  204. // Intentially use sizeof(int) instead of 2*sizeof(int)
  205. return (sizeof(HttpData)+sizeof(int)+strlen_);
  206. }
  207. virtual int cost() const { return cost_; }
  208. char* str() const { return str_; }
  209. virtual AppData* copy() {
  210. return (new HttpNormalData(*this));
  211. }
  212. };
  213. // XXX assign cost to a constant so as to be more portable
  214. const int HTTPHBDATA_COST = 32;
  215. const int HTTP_MAXURLLEN = 20;
  216. // Struct used to pack invalidation records into packets
  217. class HttpHbData : public HttpData {
  218. protected:
  219. struct InvalRec {
  220. char pg_[HTTP_MAXURLLEN]; // Maximum page id length
  221. double mtime_;
  222. // Used only to mark that this page will be send in the 
  223. // next multicast update. The updating field in this agent 
  224. // will only be set after it gets the real update.
  225. int updating_; 
  226. void copy(InvalidationRec *v) {
  227. strcpy(pg_, v->pg());
  228. mtime_ = v->mtime();
  229. updating_ = v->updating();
  230. }
  231. InvalidationRec* copyto() {
  232. return (new InvalidationRec(pg_, mtime_, updating_));
  233. }
  234. };
  235. private:
  236. int num_inv_;
  237. InvalRec* inv_rec_;
  238. inline InvalRec* inv_rec() { return inv_rec_; }
  239. public:
  240. HttpHbData(int id, int n) : 
  241. HttpData(HTTP_INVALIDATION, id), num_inv_(n) {
  242. if (num_inv_ > 0)
  243. inv_rec_ = new InvalRec[num_inv_];
  244. else
  245. inv_rec_ = NULL;
  246. }
  247. HttpHbData(HttpHbData& d) : HttpData(d) {
  248. num_inv_ = d.num_inv_;
  249. if (num_inv_ > 0) {
  250. inv_rec_ = new InvalRec[num_inv_];
  251. memcpy(inv_rec_, d.inv_rec_,num_inv_*sizeof(InvalRec));
  252. } else
  253. inv_rec_ = NULL;
  254. }
  255. virtual ~HttpHbData() { 
  256. if (inv_rec_ != NULL)
  257. delete []inv_rec_; 
  258. }
  259. virtual int size() const {
  260. return HttpData::size() + num_inv_*sizeof(InvalRec);
  261. }
  262. // XXX byte cost to appear in trace file
  263. virtual int cost() const { 
  264. // Minimum size 1 so that TCP will send a packet
  265. return (num_inv_ == 0) ? 1 : (num_inv_*HTTPHBDATA_COST); 
  266. }
  267. virtual AppData* copy() {
  268. return (new HttpHbData(*this));
  269. }
  270. inline int& num_inv() { return num_inv_; }
  271. inline void add(int i, InvalidationRec *r) {
  272. inv_rec()[i].copy(r);
  273. }
  274. inline char* rec_pg(int i) { return inv_rec()[i].pg_; }
  275. inline double& rec_mtime(int i) { return inv_rec()[i].mtime_; }
  276. void extract(InvalidationRec*& ivlist);
  277. };
  278. class HttpUpdateData : public HttpData {
  279. protected:
  280. // Pack page updates to be pushed to caches
  281. struct PageRec {
  282. char pg_[HTTP_MAXURLLEN];
  283. double mtime_;
  284. double age_;
  285. int size_;
  286. void copy(ClientPage *p) {
  287. p->name(pg_);
  288. mtime_ = p->mtime();
  289. age_ = p->age();
  290. size_ = p->size();
  291. }
  292. };
  293. private:
  294. int num_;
  295. int pgsize_;
  296. PageRec *rec_;
  297. inline PageRec* rec() { return rec_; }
  298. public:
  299. HttpUpdateData(int id, int n) : HttpData(HTTP_UPDATE, id) {
  300. num_ = n;
  301. pgsize_ = 0;
  302. if (num_ > 0)
  303. rec_ = new PageRec[num_];
  304. else
  305. rec_ = NULL;
  306. }
  307. HttpUpdateData(HttpUpdateData& d) : HttpData(d) {
  308. num_ = d.num_;
  309. pgsize_ = d.pgsize_;
  310. if (num_ > 0) {
  311. rec_ = new PageRec[num_];
  312. memcpy(rec_, d.rec_, num_*sizeof(PageRec));
  313. } else
  314. rec_ = NULL;
  315. }
  316. virtual ~HttpUpdateData() {
  317. if (rec_ != NULL)
  318. delete []rec_;
  319. }
  320. virtual int size() const { 
  321. return HttpData::size() + 2*sizeof(int)+num_*sizeof(PageRec); 
  322. }
  323. virtual int cost() const { return pgsize_; }
  324. virtual AppData* copy() {
  325. return (new HttpUpdateData(*this));
  326. }
  327. inline int num() const { return num_; }
  328. inline int pgsize() const { return pgsize_; }
  329. inline void set_pgsize(int s) { pgsize_ = s; }
  330. inline void add(int i, ClientPage *p) {
  331. rec()[i].copy(p);
  332. pgsize_ += p->size();
  333. }
  334. inline char* rec_page(int i) { return rec()[i].pg_; }
  335. inline int& rec_size(int i) { return rec()[i].size_; }
  336. inline double& rec_age(int i) { return rec()[i].age_; }
  337. inline double& rec_mtime(int i) { return rec()[i].mtime_; }
  338. };
  339. const int HTTPLEAVE_COST = 4;
  340. // Message: server leave
  341. class HttpLeaveData : public HttpData {
  342. private:
  343. int num_;
  344. int* rec_; // array of server ids which are out of contact
  345. inline int* rec() { return rec_; }
  346. public:
  347. HttpLeaveData(int id, int n) : HttpData(HTTP_LEAVE, id) {
  348. num_ = n;
  349. if (num_ > 0)
  350. rec_ = new int[num_];
  351. else
  352. rec_ = NULL;
  353. }
  354. HttpLeaveData(HttpLeaveData& d) : HttpData(d) {
  355. num_ = d.num_;
  356. if (num_ > 0) {
  357. rec_ = new int[num_];
  358. memcpy(rec_, d.rec_, num_*sizeof(int));
  359. } else
  360. rec_ = NULL;
  361. }
  362. virtual ~HttpLeaveData() { 
  363. if (rec_ != NULL)
  364. delete []rec_; 
  365. }
  366. virtual int size() const { 
  367. return HttpData::size() + (num_+1)*sizeof(int);
  368. }
  369. virtual int cost() const { return num_*HTTPLEAVE_COST; }
  370. virtual AppData* copy() {
  371. return (new HttpLeaveData(*this));
  372. }
  373. inline int num() const { return num_; }
  374. inline void add(int i, int id) {
  375. rec()[i] = id;
  376. }
  377. inline int rec_id(int i) { return rec()[i]; }
  378. };
  379. // Auxliary class
  380. class NeighborCache {
  381. public:
  382. NeighborCache(HttpMInvalCache*c, double t, LivenessTimer *timer) : 
  383. cache_(c), time_(t), down_(0), timer_(timer) {}
  384. ~NeighborCache();
  385. double time() { return time_; }
  386. void reset_timer(double time) { 
  387. time_ = time, timer_->resched(); 
  388. }
  389. int is_down() { return down_; }
  390. void down() { down_ = 1; }
  391. void up() { down_ = 0; }
  392. int num() const { return sl_.num(); }
  393. HttpMInvalCache* cache() { return cache_; }
  394. void pack_leave(HttpLeaveData&);
  395. int is_server_down(int sid);
  396. void server_down(int sid);
  397. void server_up(int sid);
  398. void invalidate(HttpMInvalCache *c);
  399. void add_server(int sid);
  400. // Maintaining neighbor cache timeout entries
  401. struct ServerEntry {
  402. ServerEntry(int sid) : server_(sid), next_(NULL), down_(0) {}
  403. int server() { return server_; }
  404. ServerEntry* next() { return next_; }
  405. int is_down() { return down_; }
  406. void down() { down_ = 1; }
  407. void up() { down_ = 0; }
  408. int server_;
  409. ServerEntry *next_;
  410. int down_;
  411. };
  412. // We cannot use template. :(((
  413. struct ServerList {
  414. ServerList() : head_(NULL), num_(0) {}
  415. void insert(ServerEntry *s) {
  416. s->next_ = head_;
  417. head_ = s;
  418. num_++;
  419. }
  420. // We don't need a detach()
  421. ServerEntry* gethead() { return head_; } // For iterations
  422. int num() const { return num_; }
  423. ServerEntry *head_;
  424. int num_;
  425. };
  426. protected:
  427. HttpMInvalCache* cache_;
  428. double time_;
  429. int down_;
  430. ServerList sl_;
  431. LivenessTimer *timer_;
  432. };
  433. #endif // ns_http_aux_h