empweb.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:18k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * empweb.cc
  4.  * Copyright (C) 2001 by the University of Southern California
  5.  * $Id: empweb.cc,v 1.20 2005/09/18 23:33:32 tomh Exp $
  6.  *
  7.  * This program is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU General Public License,
  9.  * version 2, as published by the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License along
  17.  * with this program; if not, write to the Free Software Foundation, Inc.,
  18.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  19.  *
  20.  *
  21.  * The copyright of this module includes the following
  22.  * linking-with-specific-other-licenses addition:
  23.  *
  24.  * In addition, as a special exception, the copyright holders of
  25.  * this module give you permission to combine (via static or
  26.  * dynamic linking) this module with free software programs or
  27.  * libraries that are released under the GNU LGPL and with code
  28.  * included in the standard release of ns-2 under the Apache 2.0
  29.  * license or under otherwise-compatible licenses with advertising
  30.  * requirements (or modified versions of such code, with unchanged
  31.  * license).  You may copy and distribute such a system following the
  32.  * terms of the GNU GPL for this module and the licenses of the
  33.  * other code concerned, provided that you include the source code of
  34.  * that other code when and as the GNU GPL requires distribution of
  35.  * source code.
  36.  *
  37.  * Note that people who make modified versions of this module
  38.  * are not obligated to grant this special exception for their
  39.  * modified versions; it is their choice whether to do so.  The GNU
  40.  * General Public License gives permission to release a modified
  41.  * version without this exception; this exception also makes it
  42.  * possible to release a modified version which carries forward this
  43.  * exception.
  44.  *
  45.  */
  46. //
  47. // Empirical Web traffic model that simulates Web traffic based on a set of
  48. // CDF (Cumulative Distribution Function) data derived from live tcpdump trace
  49. // The structure of this file is largely borrowed from webtraf.cc
  50. //
  51. // $Header: /cvsroot/nsnam/ns-2/empweb/empweb.cc,v 1.20 2005/09/18 23:33:32 tomh Exp $
  52. #include <tclcl.h>
  53. #include "empweb.h"
  54. // Data structures that are specific to this web traffic model and 
  55. // should not be used outside this file.
  56. //
  57. // - EmpWebTrafPage
  58. // - EmpWebTrafObject
  59. class EmpWebPage : public TimerHandler {
  60. public:
  61. EmpWebPage(int id, EmpWebTrafSession* sess, int nObj, Node* dst, int svrId) :
  62. persistOption_(0), id_(id), sess_(sess), nObj_(nObj), curObj_(0), doneObj_(0), dst_(dst), svrId_(svrId) {}
  63. virtual ~EmpWebPage() {}
  64. inline void start() {
  65. // Call expire() and schedule the next one if needed
  66. status_ = TIMER_PENDING;
  67. handle(&event_);
  68. }
  69. inline int id() const { return id_; }
  70. inline int svrId() const { return svrId_; }
  71. Node* dst() { return dst_; }
  72. void doneObject() {
  73. if (sess_->mgr()->isdebug())
  74.     printf("doneObject: %g done=%d total=%d n", Scheduler::instance().clock(), doneObj_, nObj_);
  75.   if (++doneObj_ >= nObj_) {
  76.     printf("doneObject: %g %d %d n", Scheduler::instance().clock(), doneObj_, nObj_);
  77.         sess_->donePage((void*)this);
  78. // }
  79. // sched(sess_->interObj()->value());
  80.   } else if (persistOption_) {
  81. sched(sess_->interObj()->value());
  82. }
  83. }
  84.         inline int curObj() const { return curObj_; }
  85. inline int doneObj() const { return doneObj_; }
  86. inline void set_persistOption(int opt) { persistOption_ = opt; }
  87. int persistOption_ ;  //0: http1.0  1: http1.1 ; use http1.0 as default
  88. private:
  89. virtual void expire(Event* = 0) {
  90. // Launch a request. Make sure size is not 0!
  91. if (curObj_ >= nObj_) 
  92. return;
  93. sess_->launchReq(this, LASTOBJ_++, 
  94.  (int)ceil(sess_->objSize()->value()),
  95.  (int)ceil(sess_->reqSize()->value()), sess_->id(), persistOption_);
  96. if (sess_->mgr()->isdebug())
  97. printf("expire: Session %d launched page %d obj %d nObj %d n",
  98.        sess_->id(), id_, curObj_, nObj_);
  99. }
  100. virtual void handle(Event *e) {
  101. if (sess_->mgr()->isdebug())
  102. printf("handle: Session %d launched page %d obj %dn",
  103.        sess_->id(), id_, curObj_);
  104. TimerHandler::handle(e);
  105. curObj_++;
  106. if (!persistOption_) {
  107. if (curObj_ <  nObj_) sched(sess_->interObj()->value());
  108. }
  109. }
  110. int id_;
  111. EmpWebTrafSession* sess_;
  112. int nObj_, curObj_;
  113. int doneObj_;
  114. Node* dst_;
  115. int svrId_ ;
  116. static int LASTOBJ_;
  117. };
  118. int EmpWebPage::LASTOBJ_ = 1;
  119. int EmpWebTrafSession::LASTPAGE_ = 1;
  120. int EmpWebTrafPool::LASTFLOW_ = 1;
  121. // XXX Must delete this after all pages are done!!
  122. EmpWebTrafSession::~EmpWebTrafSession() 
  123. {
  124. if (donePage_ != curPage_) {
  125. fprintf(stderr, "done pages %d != all pages %dn",
  126. donePage_, curPage_);
  127. abort();
  128. }
  129. if (status_ != TIMER_IDLE) {
  130. fprintf(stderr, "EmpWebTrafSession must be idle when deleted.n");
  131. abort();
  132. }
  133. /*
  134. if (rvInterPage_ != NULL)
  135. Tcl::instance().evalf("delete %s", rvInterPage_->name());
  136. if (rvPageSize_ != NULL)
  137. Tcl::instance().evalf("delete %s", rvPageSize_->name());
  138. if (rvInterObj_ != NULL)
  139. Tcl::instance().evalf("delete %s", rvInterObj_->name());
  140. if (rvObjSize_ != NULL)
  141. Tcl::instance().evalf("delete %s", rvObjSize_->name());
  142. if (rvReqSize_ != NULL)
  143. Tcl::instance().evalf("delete %s", rvReqSize_->name());
  144. if (rvPersistSel_ != NULL)
  145. Tcl::instance().evalf("delete %s", rvPersistSel_->name());
  146. if (rvServerSel_ != NULL)
  147. Tcl::instance().evalf("delete %s", rvServerSel_->name());
  148. */
  149. }
  150. void EmpWebTrafSession::donePage(void* ClntData) 
  151. {
  152. EmpWebPage* pg = (EmpWebPage*)ClntData;
  153. if (mgr_->isdebug()) 
  154. printf("Session %d done page %dn", id_, pg->id());
  155. if (pg->doneObj() != pg->curObj()) {
  156.         fprintf(stderr, "done objects %d != all objects %dn",
  157.                 pg->doneObj(), pg->curObj());
  158.                 abort();
  159. }
  160. //for HTTP1.1 persistent-connection
  161.         if (pg->persistOption_) {
  162.    if (!fulltcp_) { 
  163.          //recycle TCP connection
  164. mgr_->recycleTcp(ctcp_);
  165. mgr_->recycleTcp(stcp_);
  166. mgr_->recycleSink(csnk_);
  167. mgr_->recycleSink(ssnk_);
  168. } else {
  169. Tcl::instance().evalf("%s disconnect-full %s %s %s %s",
  170.         mgr_->name(),
  171. src_->name(), pg->dst()->name(),
  172.         ctcp_->name(),  stcp_->name());
  173. }
  174. }
  175. delete pg;
  176. // If all pages are done, tell my parent to delete myself
  177. if (++donePage_ >= nPage_) {
  178.     mgr_->doneSession(id_);
  179.         } else if (interPageOption_) {
  180. sched(rvInterPage_->value());
  181. // printf("donePage: %g %d %dn", Scheduler::instance().clock(), donePage_, curPage_);
  182. }
  183. }
  184. // Launch the current page
  185. void EmpWebTrafSession::expire(Event *)
  186. {
  187. // Pick destination for this page
  188. //temporary hack for isi traffic
  189. int n;
  190.         if (clientIdx_ < mgr()->nClientL_) n = 0 ; //ISI server
  191. else
  192.            n = int(ceil(serverSel()->value()));
  193.         assert((n >= 0) && (n < mgr()->nSrc_));
  194.         Node* dst = mgr()->server_[n];
  195. // Make sure page size is not 0!
  196. EmpWebPage* pg = new EmpWebPage(LASTPAGE_++, this, 
  197.   (int)ceil(rvPageSize_->value()), dst, n);
  198.         //each page either use persistent or non-persistent connection
  199. int opt = (int)ceil(this->persistSel()->value());
  200.         pg->set_persistOption(opt);
  201. if (mgr_->isdebug())
  202. printf("Session %d starting page %d, curpage %d n", 
  203.        id_, LASTPAGE_-1, curPage_);
  204.         if (pg->persistOption_) { //for HTTP1.1 persistent-connection
  205.                 mgr_->LASTFLOW_++;
  206.   int wins = int(ceil(serverWin()->value()));
  207.      int winc = int(ceil(clientWin()->value()));
  208.   int window = (wins >= winc) ? wins : winc;
  209.   int m = int(ceil(mtu()->value()));
  210.    // Choose source and dest TCP agents for both source and destination
  211. if (fulltcp_) {
  212.    ctcp_ = mgr_->picktcp(window,m);
  213.    stcp_ = mgr_->picktcp(window,m);
  214. Tcl::instance().evalf("%s connect-full %s %s %s %s",
  215.         mgr_->name(),
  216. src_->name(), pg->dst()->name(),
  217.         ctcp_->name(),  stcp_->name());
  218.                 } else {
  219.    ctcp_ = mgr_->picktcp(window,m);
  220.    stcp_ = mgr_->picktcp(window,m);
  221.    csnk_ = mgr_->picksink();
  222.    ssnk_ = mgr_->picksink();
  223. }
  224. // Tcl::instance().evalf("%s set-fid %d %s %s",                              mgr_->name(), mgr_->LASTFLOW_-1, ctcp_->name(), stcp_->name());
  225. Tcl::instance().evalf("%s set-fid %d %s %s",                              mgr_->name(), mgr_->color_, ctcp_->name(), stcp_->name());
  226. }
  227. pg->start();
  228. }
  229. void EmpWebTrafSession::handle(Event *e)
  230. {
  231. // If I haven't scheduled all my pages, do the next one
  232. TimerHandler::handle(e);
  233. ++curPage_;
  234. // XXX Notice before each page is done, it will schedule itself 
  235. // one more time, this makes sure that this session will not be
  236. // deleted after the above call. Thus the following code will not
  237. // be executed in the context of a deleted object. 
  238. if (!interPageOption_) {
  239. if (curPage_ < nPage_) {
  240. sched(rvInterPage_->value());
  241. // printf("schedule: %g %d %dn", Scheduler::instance().clock(), donePage_, curPage_);
  242. }
  243. }
  244. }
  245. // Launch a request for a particular object
  246. void EmpWebTrafSession::launchReq(void* ClntData, int obj, int size, int reqSize, int sid, int persist)
  247. {
  248.    TcpAgent* ctcp;
  249.    TcpAgent* stcp;
  250.    TcpSink* csnk;
  251.    TcpSink* ssnk;
  252. EmpWebPage* pg = (EmpWebPage*)ClntData;
  253.         if (persist) { //for HTTP1.1 persistent-connection
  254. if (mgr_->isdebug()) {
  255. printf("HTTP1.1n");
  256. }
  257. // use the same connection
  258. ctcp = ctcp_;
  259. stcp = stcp_;
  260. if (fulltcp_) {
  261. csnk = 0;
  262. ssnk = 0;
  263. } else {
  264.    csnk = csnk_;
  265.    ssnk = ssnk_;
  266. }
  267.         } else { //for HTTP1.0 non-consistent connection
  268. if (mgr_->isdebug()) {
  269. printf("HTTP1.0n");
  270. }
  271. mgr_->LASTFLOW_++;
  272.   int wins = int(ceil(serverWin()->value()));
  273.      int winc = int(ceil(clientWin()->value()));
  274.   int window = (wins >= winc) ? wins : winc;
  275.   int m = int(ceil(mtu()->value()));
  276.    // Choose source and dest TCP agents for both source and destination
  277. ctcp = mgr_->picktcp(window,m);
  278. stcp = mgr_->picktcp(window,m);
  279. Tcl::instance().evalf("%s set-fid %d %s %s",
  280.       mgr_->name(), mgr_->color_, ctcp->name(), stcp->name());
  281. if (fulltcp_) {
  282. csnk = 0;
  283. ssnk = 0;
  284. } else {
  285.    csnk = mgr_->picksink();
  286.    ssnk = mgr_->picksink();
  287. }
  288. }
  289. // Setup new TCP connection and launch request
  290. // size and reqSize are in the unit of bytes in fulltcp mode
  291. // but in the unit of packet in halftcp mode
  292. if (fulltcp_) {
  293. Tcl::instance().evalf("%s launch-req-full %d %d %s %s %s %s %d %d %d %d",
  294.                               mgr_->name(), obj, pg->id(), 
  295.       src_->name(), pg->dst()->name(),
  296.       ctcp->name(),  
  297.       stcp->name(),  
  298.       size, reqSize, ClntData,persist);
  299. } else {
  300. assert (csnk != 0 && ssnk != 0);
  301. Tcl::instance().evalf("%s launch-req %d %d %s %s %s %s %s %s %d %d %d %d",
  302.                               mgr_->name(), obj, pg->id(), 
  303.       src_->name(), pg->dst()->name(),
  304.       ctcp->name(), csnk->name(), 
  305.       stcp->name(), ssnk->name(), 
  306.       size, reqSize, ClntData,
  307.       persist);
  308. }
  309. if (mgr_->isdebug()) {
  310.   printf("size=%d  obj=%d  page=%d  sess=%d  %g src=%d dst=%dn", size, obj, pg->id(), id_, Scheduler::instance().clock(), src_->address(), pg->dst()->address());
  311. }
  312. }
  313. static class EmpWebTrafPoolClass : public TclClass {
  314. public:
  315.         EmpWebTrafPoolClass() : TclClass("PagePool/EmpWebTraf") {}
  316.         TclObject* create(int, const char*const*) {
  317. return (new EmpWebTrafPool());
  318. }
  319. } class_empwebtrafpool;
  320. EmpWebTrafPool::~EmpWebTrafPool()
  321. {
  322. if (session_ != NULL) {
  323. for (int i = 0; i < nSession_; i++)
  324. delete session_[i];
  325. delete []session_;
  326. }
  327. if (server_ != NULL)
  328. delete []server_;
  329. if (client_ != NULL)
  330. delete []client_;
  331. // XXX Destroy tcpPool_ and sinkPool_ ?
  332. }
  333. void EmpWebTrafPool::delay_bind_init_all()
  334. {
  335. delay_bind_init_one("debug_");
  336. PagePool::delay_bind_init_all();
  337. }
  338. int EmpWebTrafPool::delay_bind_dispatch(const char *varName,const char *localName,
  339.      TclObject *tracer)
  340. {
  341. if (delay_bind_bool(varName, localName, "debug_", &debug_, tracer)) 
  342. return TCL_OK;
  343. return PagePool::delay_bind_dispatch(varName, localName, tracer);
  344. }
  345. EmpWebTrafPool::EmpWebTrafPool() : 
  346. concurrentSess_(0), nSrc_(0), server_(NULL), session_(NULL), nClient_(0), client_(NULL), nTcp_(0), nSink_(0), fulltcp_(0)
  347. {
  348.         bind("fulltcp_", &fulltcp_);
  349. LIST_INIT(&tcpPool_);
  350. LIST_INIT(&sinkPool_);
  351. }
  352. TcpAgent* EmpWebTrafPool::picktcp(int win, int mtu)
  353. {
  354. TcpAgent* a = (TcpAgent*)detachHead(&tcpPool_);
  355. if (a == NULL) {
  356. Tcl& tcl = Tcl::instance();
  357. tcl.evalf("%s alloc-tcp %d %d", name(), win, mtu);
  358. a = (TcpAgent*)lookup_obj(tcl.result());
  359. if (a == NULL) {
  360. fprintf(stderr, "Failed to allocate a TCP agentn");
  361. abort();
  362. }
  363. } else 
  364. nTcp_--;
  365. return a;
  366. }
  367. TcpSink* EmpWebTrafPool::picksink()
  368. {
  369. TcpSink* a = (TcpSink*)detachHead(&sinkPool_);
  370. if (a == NULL) {
  371. Tcl& tcl = Tcl::instance();
  372. tcl.evalf("%s alloc-tcp-sink", name());
  373. a = (TcpSink*)lookup_obj(tcl.result());
  374. if (a == NULL) {
  375. fprintf(stderr, "Failed to allocate a TCP sinkn");
  376. abort();
  377. }
  378. } else 
  379. nSink_--;
  380. return a;
  381. }
  382. void EmpWebTrafPool::recycleTcp(Agent* a)
  383. {
  384. if (fulltcp_) {
  385. delete a;
  386. } else {
  387. if (a == NULL) {
  388. fprintf(stderr, "Failed to recycle TCP agentn");
  389. abort();
  390. }
  391. nTcp_++;
  392. insertAgent(&tcpPool_, a);
  393. }
  394. }
  395. void EmpWebTrafPool::recycleSink(Agent* a)
  396. {
  397. if (fulltcp_) {
  398. delete a;
  399. } else {
  400. if (a == NULL) {
  401. fprintf(stderr, "Failed to recycle Sink agentn");
  402. abort();
  403. }
  404. nSink_++;
  405. insertAgent(&sinkPool_, a);
  406. }
  407. }
  408. int EmpWebTrafPool::command(int argc, const char*const* argv)
  409. {
  410. if (argc == 3) {
  411. if (strcmp(argv[1], "set-num-session") == 0) {
  412. if (session_ != NULL) {
  413. for (int i = 0; i < nSession_; i++) 
  414. delete session_[i];
  415. delete []session_;
  416. }
  417. nSession_ = atoi(argv[2]);
  418. session_ = new EmpWebTrafSession*[nSession_];
  419. memset(session_, 0, sizeof(EmpWebTrafSession*)*nSession_);
  420. return (TCL_OK);
  421. } else if (strcmp(argv[1], "set-num-server-lan") == 0) {
  422. nSrcL_ = atoi(argv[2]);
  423. if (nSrcL_ >  nSrc_) {
  424. fprintf(stderr, "Wrong server index %dn", nSrcL_);
  425. return TCL_ERROR;
  426. }
  427. return (TCL_OK);
  428. } else if (strcmp(argv[1], "set-num-remote-client") == 0) {
  429. nClientL_ = atoi(argv[2]);
  430. if (nClientL_ > nClient_) {
  431. fprintf(stderr, "Wrong client index %dn", nClientL_);
  432. return TCL_ERROR;
  433. }
  434. return (TCL_OK);
  435. } else if (strcmp(argv[1], "set-num-server") == 0) {
  436. nSrc_ = atoi(argv[2]);
  437. if (server_ != NULL) 
  438. delete []server_;
  439. server_ = new Node*[nSrc_];
  440. return (TCL_OK);
  441. } else if (strcmp(argv[1], "set-num-client") == 0) {
  442. nClient_ = atoi(argv[2]);
  443. if (client_ != NULL) 
  444. delete []client_;
  445. client_ = new Node*[nClient_];
  446. return (TCL_OK);
  447. } else if (strcmp(argv[1], "set-interPageOption") == 0) {
  448. int option = atoi(argv[2]);
  449. if (session_ != NULL) {
  450. for (int i = 0; i < nSession_; i++) {
  451. EmpWebTrafSession* p = session_[i];
  452. p->set_interPageOption(option);
  453. }
  454. }
  455. return (TCL_OK);
  456. } else if (strcmp(argv[1], "doneObj") == 0) {
  457.         EmpWebPage* p = (EmpWebPage*)atol(argv[2]);
  458. p->doneObject();
  459.                 
  460. return (TCL_OK);
  461. }
  462. } else if (argc == 4) {
  463. if (strcmp(argv[1], "set-server") == 0) {
  464. Node* cli = (Node*)lookup_obj(argv[3]);
  465. if (cli == NULL)
  466. return (TCL_ERROR);
  467. int nc = atoi(argv[2]);
  468. if (nc >= nSrc_) {
  469. fprintf(stderr, "Wrong server index %dn", nc);
  470. return TCL_ERROR;
  471. }
  472. server_[nc] = cli;
  473. return (TCL_OK);
  474. } else if (strcmp(argv[1], "set-client") == 0) {
  475. Node* s = (Node*)lookup_obj(argv[3]);
  476. if (s == NULL)
  477. return (TCL_ERROR);
  478. int n = atoi(argv[2]);
  479. if (n >= nClient_) {
  480. fprintf(stderr, "Wrong client index %dn", n);
  481. return TCL_ERROR;
  482. }
  483. client_[n] = s;
  484. return (TCL_OK);
  485. } else if (strcmp(argv[1], "recycle") == 0) {
  486. // <obj> recycle <tcp> <sink>
  487. //
  488. // Recycle a TCP source/sink pair
  489. Agent* tcp = (Agent*)lookup_obj(argv[2]);
  490. Agent* snk = (Agent*)lookup_obj(argv[3]);
  491. if ((tcp == NULL) || (snk == NULL))
  492. return (TCL_ERROR);
  493. // XXX TBA: recycle tcp agents
  494. if (fulltcp_) {
  495. delete tcp;
  496. delete snk;
  497. } else {
  498. nTcp_++, nSink_++;
  499. insertAgent(&tcpPool_, tcp);
  500. insertAgent(&sinkPool_, snk);
  501. }
  502. return (TCL_OK);
  503. }
  504. } else if (argc == 17) {
  505. if (strcmp(argv[1], "create-session") == 0) {
  506. // <obj> create-session <session_index>
  507. //   <pages_per_sess> <launch_time>
  508. //   <inter_page_rv> <page_size_rv>
  509. //   <inter_obj_rv> <obj_size_rv>
  510. //   <req_size_rv> <persist_sel_rv> <server_sel_rv>
  511. //   <client_win_rv> <server_win_rv> <mtu_rv>
  512. //   <inbound/outbound flag> <color>
  513. int n = atoi(argv[2]);
  514. if ((n < 0)||(n >= nSession_)||(session_[n] != NULL)) {
  515. fprintf(stderr,"Invalid session index %dn",n);
  516. return (TCL_ERROR);
  517. }
  518. int npg = (int)strtod(argv[3], NULL);
  519. double lt = strtod(argv[4], NULL);
  520. int flip = atoi(argv[15]);
  521. if ((flip < 0)||(flip > 1)) {
  522. fprintf(stderr,"Invalid I/O flag %dn",flip);
  523. return (TCL_ERROR);
  524. }
  525.                         //for SPAWAR demo
  526. color_ = atoi(argv[16]);
  527.                         int cl;
  528. if (flip == 1) 
  529.                           cl = int(floor(Random::uniform(0, nClientL_)));
  530. else
  531.                           cl = int(floor(Random::uniform(nClientL_, nClient_)));
  532.                         assert((cl >= 0) && (cl < nClient_));
  533.                         Node* c=client_[cl];
  534. EmpWebTrafSession* p = 
  535. new EmpWebTrafSession(this, c, npg, n, nSrc_, cl,fulltcp_);
  536. int res = lookup_rv(p->interPage(), argv[5]);
  537. res = (res == TCL_OK) ? 
  538. lookup_rv(p->pageSize(), argv[6]) : TCL_ERROR;
  539. res = (res == TCL_OK) ? 
  540. lookup_rv(p->interObj(), argv[7]) : TCL_ERROR;
  541. res = (res == TCL_OK) ? 
  542. lookup_rv(p->objSize(), argv[8]) : TCL_ERROR;
  543. res = (res == TCL_OK) ? 
  544. lookup_rv(p->reqSize(), argv[9]) : TCL_ERROR;
  545. res = (res == TCL_OK) ? 
  546. lookup_rv(p->persistSel(), argv[10]) : TCL_ERROR;
  547. res = (res == TCL_OK) ? 
  548. lookup_rv(p->serverSel(), argv[11]) : TCL_ERROR;
  549. res = (res == TCL_OK) ? 
  550. lookup_rv(p->serverWin(), argv[12]) : TCL_ERROR;
  551. res = (res == TCL_OK) ? 
  552. lookup_rv(p->clientWin(), argv[13]) : TCL_ERROR;
  553. res = (res == TCL_OK) ? 
  554. lookup_rv(p->mtu(), argv[14]) : TCL_ERROR;
  555. if (res == TCL_ERROR) {
  556. delete p;
  557. fprintf(stderr, "Invalid random variablen");
  558. return (TCL_ERROR);
  559. }
  560. p->sched(lt);
  561. session_[n] = p;
  562.                            
  563. return (TCL_OK);
  564. }
  565. }
  566. return PagePool::command(argc, argv);
  567. }