/* Web Polygraph http://www.web-polygraph.org/ * (C) 2003-2006 The Measurement Factory * Licensed under the Apache License, Version 2.0 */ #include "pgl/pgl.h" #include "xstd/String.h" #include "xstd/rndDistrs.h" #include "base/RndPermut.h" #include "pgl/PglBoolSym.h" #include "pgl/PglIntSym.h" #include "pgl/PglNumSym.h" #include "pgl/PglRateSym.h" #include "pgl/PglRec.h" #include "pgl/PglStringSym.h" #include "pgl/PglNetAddrSym.h" #include "pgl/PglArraySym.h" #include "pgl/AclSym.h" #include "pgl/DnsResolverSym.h" #include "pgl/SessionSym.h" #include "pgl/RobotSym.h" const String RobotSym::TheType = "Robot"; static String strAcl = "acl"; static String strAddrArr = "addr[]"; static String strAuth_error = "auth_error"; static String strCredentials = "credentials"; static String strDns_resolver = "dns_resolver"; static String strEmbed_recur = "embed_recur"; static String strForeign_trace = "foreign_trace"; static String strRaw_uri_thrower = "raw_uri_thrower"; static String strIcp_port = "icp_port"; static String strInterests = "interests"; static String strMinimize_new_conn = "minimize_new_conn"; static String strOpen_conn_lmt = "open_conn_lmt"; static String strOrigins = "origins"; static String strPeer_http = "peer_http"; static String strPeer_icp = "peer_icp"; static String strPrivate_cache_cap = "private_cache_cap"; static String strProxies = "proxies"; static String strRecurrence = "recurrence"; static String strReq_inter_arrival = "req_inter_arrival"; static String strReq_methods = "req_methods"; static String strContainerTags = "container_tags"; static String strReq_rate = "req_rate"; static String strReq_types = "req_types"; static String strSession = "session"; static String strStringArr = "string[]"; static String strTime_distr = "time_distr"; static String strFloat_distr = "float_distr"; static String strSize_distr = "size_distr"; static String strUnique_urls = "unique_urls"; static String strWait_xact_lmt = "wait_xact_lmt"; static String strPipeline_depth = "pipeline_depth"; static String strCookies_keep_lmt = "cookies_keep_lmt"; static String strAcceptContentEncodings = "accept_content_encodings"; RobotSym::RobotSym(): AgentSym(TheType) { theRec->bAdd(strAddrArr, strProxies, 0); theRec->bAdd(strAddrArr, strOrigins, 0); theRec->bAdd(RateSym::TheType, strReq_rate, 0); theRec->bAdd(strTime_distr, strReq_inter_arrival, 0); theRec->bAdd(NumSym::TheType, strRecurrence, 0); theRec->bAdd(NumSym::TheType, strEmbed_recur, 0); theRec->bAdd(strStringArr, strInterests, 0); theRec->bAdd(strStringArr, strReq_types, 0); theRec->bAdd(strStringArr, strReq_methods, 0); theRec->bAdd(strStringArr, strContainerTags, 0); theRec->bAdd(strStringArr, strAcceptContentEncodings, 0); theRec->bAdd(IntSym::TheType, strPrivate_cache_cap, 0); theRec->bAdd(BoolSym::TheType, strUnique_urls, 0); theRec->bAdd(IntSym::TheType, strOpen_conn_lmt, 0); theRec->bAdd(IntSym::TheType, strWait_xact_lmt, 0); theRec->bAdd(NumSym::TheType, strMinimize_new_conn, 0); theRec->bAdd(strStringArr, strCredentials, 0); theRec->bAdd(NumSym::TheType, strAuth_error, 0); theRec->bAdd(AclSym::TheType, strAcl, new AclSym); theRec->bAdd(SessionSym::TheType, strSession, new SessionSym); theRec->bAdd(IntSym::TheType, strIcp_port, 0); theRec->bAdd(NetAddrSym::TheType, strPeer_http, 0); theRec->bAdd(NetAddrSym::TheType, strPeer_icp, 0); theRec->bAdd(DnsResolverSym::TheType, strDns_resolver, new DnsResolverSym); theRec->bAdd(StringSym::TheType, strForeign_trace, 0); theRec->bAdd(StringSym::TheType, strRaw_uri_thrower, 0); theRec->bAdd(strFloat_distr, strPipeline_depth, 0); theRec->bAdd(strFloat_distr, strCookies_keep_lmt, 0); } RobotSym::RobotSym(const String &aType, PglRec *aRec): AgentSym(aType, aRec) { } bool RobotSym::isA(const String &type) const { return AgentSym::isA(type) || type == TheType; } SynSym *RobotSym::dupe(const String &type) const { if (isA(type)) return new RobotSym(this->type(), theRec->clone()); return AgentSym::dupe(type); } bool RobotSym::reqRate(double &rate) const { return getRate(strReq_rate, rate); } bool RobotSym::reqInterArrival(RndDistr *&iad) const { iad = getDistr(strReq_inter_arrival); double rr = -1; const bool hasRR = reqRate(rr); if (hasRR && iad) cerr << loc() << ": cannot specify both request rate" << " and inter-arrival distribution" << endl << xexit; if (iad) return true; if (!hasRR) return false; if (rr <= 0) return true; // iad is nil // poisson request stream (default) is modeled using an exponential // distribution with a mean of a given request rate // all clients should share one rng static RndGen rng(GlbPermut(rndRobotSymReqInterArrival)); iad = new ExpDistr(&rng, 1/rr); return true; } bool RobotSym::recurRatio(double &ratio) const { return getDouble(strRecurrence, ratio); } bool RobotSym::embedRecurRatio(double &ratio) const { return getDouble(strEmbed_recur, ratio); } bool RobotSym::uniqueUrls(bool &set) const { return getBool(strUnique_urls, set); } bool RobotSym::openConnLimit(int &lmt) const { return getInt(strOpen_conn_lmt, lmt); } bool RobotSym::waitXactLimit(int &lmt) const { return getInt(strWait_xact_lmt, lmt); } bool RobotSym::minimizeNewConn(double &prob) const { return getDouble(strMinimize_new_conn, prob); } SessionSym *RobotSym::session() const { const SynSym *ss = getRecSym(strSession); return ss ? &((SessionSym&)ss->cast(SessionSym::TheType)) : 0; } bool RobotSym::authError(double &prob) const { return getDouble(strAuth_error, prob); } bool RobotSym::icpPort(int &port) const { return getInt(strIcp_port, port); } NetAddr RobotSym::peerHttp() const { return getNetAddr(strPeer_http); } NetAddr RobotSym::peerIcp() const { return getNetAddr(strPeer_icp); } AclSym *RobotSym::acl() const { SynSymTblItem *i = 0; Assert(theRec->find(strAcl, i)); return i->sym() ? &((AclSym&)i->sym()->cast(AclSym::TheType)) : 0; } DnsResolverSym *RobotSym::dnsResolver() const { SynSymTblItem *di = 0; Assert(theRec->find(strDns_resolver, di)); return di->sym() ? &((DnsResolverSym&)di->sym()->cast(DnsResolverSym::TheType)) : 0; } bool RobotSym::privCache(int &capacity) const { return getInt(strPrivate_cache_cap, capacity); } bool RobotSym::proxies(Array &addrs) const { return getNetAddrs(strProxies, addrs); } bool RobotSym::origins(Array &addrs) const { return getNetAddrs(strOrigins, addrs); } bool RobotSym::origins(Array &addrs, RndDistr *&selector) const { SynSymTblItem *oi = 0; Assert(theRec->find(strOrigins, oi)); if (!oi->sym()) return false; // undefined // build address array and selector origins(addrs); ArraySym &os = (ArraySym&)oi->sym()->cast(ArraySym::TheType); selector = os.makeSelector(kind() + "-origins"); return true; } String RobotSym::msgTypesField() const { return strReq_types; } bool RobotSym::credentials(Array &creds) const { return getStrings(strCredentials, creds); } bool RobotSym::containerTags(Array &tags) const { return getStrings(strContainerTags, tags); } bool RobotSym::acceptedContentCodings(Array &codings) const { return getStrings(strAcceptContentEncodings, codings); } bool RobotSym::interests(Array &istrs, Array &iprobs) const { if (ArraySym *a = getArraySym(strInterests)) { a->copyProbs(iprobs); ArraySymExportM(StringSym, *a, StringSym::TheType, istrs); return true; } return false; } RndDistr *RobotSym::interests(const StrIdentifier &interestKinds) const { return namesToDistr(strInterests, interestKinds); } RndDistr *RobotSym::reqMethods(const StrIdentifier &reqMethodNames) const { return namesToDistr(strReq_methods, reqMethodNames); } RndDistr *RobotSym::pipelineDepth() const { return getDistr(strPipeline_depth); } String RobotSym::foreignTrace() const { return getString(strForeign_trace); } String RobotSym::rawUriThrower() const { return getString(strRaw_uri_thrower); } RndDistr *RobotSym::cookiesKeepLimit() const { return getDistr(strCookies_keep_lmt); }