示例#1
0
int
session_issue_call (Sess *sess, Call *call)
{
  Call_Private_Data *cpriv;
  Sess_Private_Data *priv;
  struct Conn_Info *ci;
  int i;

  priv = SESS_PRIVATE_DATA (sess);

  cpriv = CALL_PRIVATE_DATA (call);
  cpriv->sess = sess;

  for (i = 0; i < param.max_conns; ++i)
    {
      ci = priv->conn_info + i;
      if (ci->num_pending < param.max_piped)
	{
	  ++ci->num_pending;
	  ci->call[ci->wr] = call;
	  call_inc_ref (call);
	  ci->wr = (ci->wr + 1) % MAX_PIPED;
	  send_calls (sess, ci);
	  return 0;
	}
    }
  fprintf (stderr, "%s.session_issue_call: too many calls pending!\n"
	   "\tIncrease --max-connections and/or --max-piped-calls.\n",
	   prog_name);
  exit (1);
}
示例#2
0
static void
call_recv_hdr (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Call_Private_Data *cpriv;
  Sess_Private_Data *priv;
  struct iovec *line;
  Call *call;
  Sess *sess;
  char *hdr;

  assert (et == EV_CALL_RECV_HDR && object_is_call (obj));
  call = (Call *) obj;
  cpriv = CALL_PRIVATE_DATA (call);
  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);

  line = callarg.vp;
  hdr = line->iov_base;

  switch (tolower (hdr[0]))
    {
    case 'c':
      if (line->iov_len >= 23
	  && strncasecmp (hdr + 1, "ontent-type: text/html", 22) == 0)
	cpriv->state = P_HTML;
      break;

    case 'l':
      if (line->iov_len > 10
	  && strncasecmp (hdr + 1, "ocation: ", 9) == 0)
	fetch_uri (sess, priv, cpriv, hdr + 10, line->iov_len - 10);
      break;
    }

}
示例#3
0
static void
sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Sess_Private_Data *priv;
  struct Conn_Info *ci;
  Sess *sess;
  int i, j, rd;

  assert (et == EV_SESS_DESTROYED && object_is_sess (obj));
  sess = (Sess *) obj;
  priv = SESS_PRIVATE_DATA (sess);

  for (i = 0; i < param.max_conns; ++i)
    {
      ci = priv->conn_info + i;

      if (ci->conn)
	core_close (ci->conn);

      rd = ci->rd;
      for (j = 0; j < ci->num_pending; ++j)
	{
	  call_dec_ref (ci->call[rd]);
	  rd = (rd + 1) % MAX_PIPED;
	}
    }
}
示例#4
0
static void
call_issue (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Call_Private_Data *cpriv;
  Sess_Private_Data *priv;
  Sess *sess;
  Call *call;

  assert (et == EV_CALL_ISSUE && object_is_call (obj));
  call = (Call *) obj;
  cpriv = CALL_PRIVATE_DATA (call);

  if (cpriv->cookie_present)
    /* don't do anything if cookie has been set already */
    return;

  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);

  if (priv->cookie_len > 0)
    {
      if (DBG > 1)
	fprintf (stderr, "call_issue.%ld: inserting `%s'\n",
		 call->id, priv->cookie);
      cpriv->cookie_present = 1;
      memcpy (cpriv->cookie, priv->cookie, priv->cookie_len + 1);
      call_append_request_header (call, cpriv->cookie, priv->cookie_len);
    }
}
示例#5
0
/* Create a new session.  */
static int
sess_create (Any_Type arg)
{
  Sess_Private_Data *priv;
  Sess *sess;

  if (num_sessions_generated++ >= param.wsess.num_sessions)
    return -1;

  sess = sess_new ();
  if (!sess)
    return 1;

  priv = SESS_PRIVATE_DATA (sess);

  priv->num_calls_target = param.burst_len;
  issue_calls (sess, SESS_PRIVATE_DATA (sess));
  return 0;
}
示例#6
0
static void
user_think_time_expired(struct Timer *t, Any_Type arg) {
    Sess *sess = arg.vp;
    Sess_Private_Data *priv;

    assert(object_is_sess(sess));

    priv = SESS_PRIVATE_DATA (sess);
    priv->timer = 0;
    issue_calls(sess, priv);
}
示例#7
0
static void
sess_created (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Sess_Private_Data *priv;
  Sess *sess;

  assert (et == EV_SESS_NEW && object_is_sess (obj));
  sess = (Sess *) obj;
  priv = SESS_PRIVATE_DATA (sess);
  priv->birth_time = timer_now ();
}
示例#8
0
static void
conn_connected (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Sess_Private_Data *priv;
  Sess *sess;
  Conn *conn;

  assert (et == EV_CONN_CONNECTED && object_is_conn (obj));
  conn = (Conn *) obj;
  sess = session_get_sess_from_conn (conn);
  priv = SESS_PRIVATE_DATA (sess);
  ++priv->num_conns;
}
示例#9
0
static void
call_done (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Sess_Private_Data *priv;
  Sess *sess;
  Call *call;

  assert (et == EV_CALL_RECV_STOP && object_is_call (obj));
  call = (Call *) obj;
  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);
  ++priv->num_calls_completed;
}
示例#10
0
size_t
session_current_qlen (Sess *sess)
{
  Sess_Private_Data *priv;
  size_t num_pending = 0;
  int i;

  priv = SESS_PRIVATE_DATA (sess);

  for (i = 0; i < param.max_conns; ++i)
    num_pending += priv->conn_info[i].num_pending;

  return num_pending;
}
示例#11
0
/* Create a new session.  */
static int
sess_create (Any_Type arg)
{
  Sess *sess;

  if (num_sessions_generated++ >= param.wsesspage.num_sessions)
    return -1;

  sess = sess_new ();
  if (!sess)
    return 1;

  issue_calls (sess, SESS_PRIVATE_DATA (sess));
  return 0;
}
示例#12
0
static void
sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Sess_Private_Data *priv;
  Sess *sess;
  Time now;
  
  assert (et == EV_SESS_DESTROYED && object_is_sess (obj));
  sess = (Sess *) obj;

  priv = SESS_PRIVATE_DATA (sess);
 
  now=timer_now();
  if(now>=end)core_exit();
  if (++num_sessions_destroyed >= param.wsessreq.num_sessions) core_exit ();
}
示例#13
0
static void
sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  size_t old_size, new_size;
  Sess_Private_Data *priv;
  Sess *sess;
  Time delta, now = timer_now ();

  assert (et == EV_SESS_DESTROYED && object_is_sess (obj));
  sess = (Sess *) obj;
  priv = SESS_PRIVATE_DATA (sess);

  delta = (now - priv->birth_time);
  if (sess->failed)
    {
      ++st.num_failed;
      st.failtime_sum += delta;
    }
  else
    {
      st.num_conns += priv->num_conns;
      ++st.num_completed_since_last_sample;
      ++st.num_completed;
      st.lifetime_sum += delta;
    }

  if (priv->num_calls_completed > st.longest_session)
    {
      st.longest_session = priv->num_calls_completed;

      if (st.longest_session >= st.len_hist_alloced)
	{
	  old_size = st.len_hist_alloced*sizeof (st.len_hist[0]);
	  st.len_hist_alloced = st.longest_session + 16;
	  new_size = st.len_hist_alloced*sizeof (st.len_hist[0]);

	  st.len_hist = realloc (st.len_hist, new_size);
	  if (!st.len_hist)
	    {
	      fprintf (stderr, "%s.sess_stat: Out of memory\n", prog_name);
	      exit (1);
	    }
	  memset ((char *) st.len_hist + old_size, 0, new_size - old_size);
	}
    }
  ++st.len_hist[priv->num_calls_completed];
}
示例#14
0
static void
call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Call_Private_Data *cpriv;
  Sess_Private_Data *priv;
  Any_Type arg;
  Sess *sess;
  Call *call;

  assert (et == EV_CALL_DESTROYED && object_is_call (obj));

  call = (Call *) obj;
  cpriv = CALL_PRIVATE_DATA (call);
  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);

  if (cpriv->to_free)
    {
      free (cpriv->to_free);
      cpriv->to_free = 0;
    }
  ++priv->num_destroyed;

  if (sess->failed)
    return;

  if (priv->uri_list)
    /* there are some queued URI's which we may be able to issue now */
    issue_calls (sess, priv);
  else if (priv->num_destroyed >= priv->num_created)
    {
      /* we're done with this burst */
      if (++priv->num_reqs_completed >= param.wsesspage.num_reqs)
	/* we're done with this session */
	sess_dec_ref (sess);
      else 
	{
	  /* schedule the user-think-time timer */
	  priv->num_created = 0;
	  assert (!priv->timer);
	  arg.vp = sess;
	  priv->timer = timer_schedule (user_think_time_expired, arg,
					param.wsesspage.think_time);
	}
    }
}
示例#15
0
static void
sess_destroyed(Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) {
    Sess_Private_Data *priv;
    Sess *sess;

    assert(et == EV_SESS_DESTROYED && object_is_sess(obj));
    sess = (Sess *) obj;

    priv = SESS_PRIVATE_DATA (sess);
    if (priv->timer) {
        timer_cancel(priv->timer);
        priv->timer = 0;
    }

    if (++num_sessions_destroyed >= param.wsesslog.num_sessions)
        core_exit();
}
示例#16
0
static void
call_recv_hdr (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  char *hdr, *start, *end;
  Sess_Private_Data *priv;
  size_t len;
  struct iovec *line;
  Sess *sess;
  Call *call;

  assert (et == EV_CALL_RECV_HDR && object_is_call (obj));
  call = (Call *) obj;
  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);

  line = callarg.vp;
  hdr = line->iov_base;
  if (tolower (hdr[0]) == 's' && line->iov_len > 12
      && strncasecmp (hdr + 1, "et-cookie: ", 11) == 0)
    {
      /* munch time! */
      start = hdr + 12;
      end = strchr (start, ';');
      if (!end)
	end = hdr + line->iov_len;
      len = end - start;
      if (DBG > 0 && priv->cookie_len > 0)
	fprintf (stderr, "%s: can't handle more than one "
		 "cookie at a time, replacing existing one\n", prog_name);
      if (len + 10 >= MAX_COOKIE_LEN)
	{
	  fprintf (stderr, "%s.sess_cookie: truncating cookie to %d bytes\n",
		   prog_name, MAX_COOKIE_LEN - 11);
	  len = MAX_COOKIE_LEN - 11;
	}
      memcpy (priv->cookie, "Cookie: ", 8);
      memcpy (priv->cookie + 8, start, len);
      memcpy (priv->cookie + 8 + len, "\r\n", 2);
      priv->cookie[10 + len] = '\0';
      priv->cookie_len = len + 10;

      if (DBG > 0)
	fprintf (stderr, "%s: got cookie `%s'\n", prog_name, start);
    }
}
示例#17
0
static void
call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Any_Type arg;
  Sess *sess;
  Call *call;
  Sess_Private_Data *priv;

  assert (et == EV_CALL_DESTROYED && object_is_call (obj));

  call = (Call *) obj;
  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);

  ++priv->num_calls_destroyed;

  if (priv->num_calls_destroyed >= param.wsess.num_calls)
    {
      /* we're done with this session */
      if (!sess->failed)
	sess_dec_ref (sess);
    }
  else if (priv->num_calls_in_this_burst < param.burst_len)
    /* now that we received the reply to the first call in this burst,
       create the remaining calls */
    issue_calls (sess, priv);
  else if (priv->num_calls_destroyed >= priv->num_calls_target)
    {
      /* we're done with this burst---schedule the user-think-time timer */
      priv->num_calls_in_this_burst = 0;
      priv->num_calls_target += param.burst_len;
      assert (!priv->timer);
      arg.vp = sess;
      priv->timer = timer_schedule (user_think_time_expired, arg,
				    param.wsess.think_time);
    }
}
示例#18
0
static void
call_recv_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Call_Private_Data *cpriv;
  Sess_Private_Data *priv;
  const char *cp, *end;
  struct iovec *line;
  Sess *sess;
  Call *call;
  int ch;

  assert (et == EV_CALL_RECV_DATA && object_is_call (obj));
  call = (Call *) obj;
  cpriv = CALL_PRIVATE_DATA (call);
  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);

  if (cpriv->state == P_INITIAL)
    return;	/* not an html object */

  line = callarg.vp;
  cp = line->iov_base;
  end = cp + line->iov_len;
  while (cp < end)
    {
      ch = *cp++;

      switch (cpriv->state)
	{
	case P_INITIAL:
	  break;

	case P_HTML:
	  cpriv->buf_len = 0;
	  if (ch == '<')
	    cpriv->state = P_CMD;
	  break;

	case P_CMD:
	  if (isspace (ch) || ch == '=')
	    {
	      if (cpriv->buf_len > 0)
		{
		  if (DBG > 3)
		    fprintf (stderr, "found command `%.*s'\n",
			     cpriv->buf_len, cpriv->buf);

		  if (cpriv->buf_len == 3
		      && strcmp (cpriv->buf, "!--") == 0)
		    cpriv->state = P_DASH_ONE;
		  else if (cpriv->buf_len == 5
			   && strncasecmp (cpriv->buf, "frame", 5) == 0)
		    cpriv->state = P_SRC;
		  else if (cpriv->buf_len == 6
			   && strncasecmp (cpriv->buf, "iframe", 6) == 0)
		    cpriv->state = P_SRC;
		  else if (cpriv->buf_len == 6
			   && strncasecmp (cpriv->buf, "data", 6) == 0)
		    cpriv->state = P_DATA;
		  else if (cpriv->buf_len == 3
			   && strncasecmp (cpriv->buf, "img", 3) == 0)
		    cpriv->state = P_SRC;
		  cpriv->buf_len = 0;
		}
	      else
		cpriv->state = P_HTML;
	    }
	  else if (ch == '>')
	    cpriv->state = P_HTML;
	  else if (cpriv->buf_len < sizeof (cpriv->buf))
	    cpriv->buf[cpriv->buf_len++] = ch;
	  break;

	case P_DASH_ONE:
	  if (ch == '-')
	    cpriv->state = P_DASH_TWO;
	  break;

	case P_DASH_TWO:
	  cpriv->state = (ch == '-') ? P_RANGLE : P_DASH_ONE;
	  break;

	case P_RANGLE:
	  if (ch == '>')
	    cpriv->state = P_HTML;
	  break;

	case P_SRC:
	  if (ch == '>')
	    cpriv->state = P_HTML;
	  else
	    {
	      cpriv->buf[cpriv->buf_len++] = ch;
	      if (cpriv->buf_len == 4)
		{
		  if (strncasecmp (cpriv->buf, "src=", 4) == 0)
		    {
		      cpriv->state = P_LQUOTE;
		      cpriv->buf_len = 0;
		    }
		  else
		    {
		      memcpy (cpriv->buf, cpriv->buf + 1, 3);
		      cpriv->buf_len = 3;
		    }
		}
	    }
	  break;

	case P_DATA:
	  if (ch == '>')
	    cpriv->state = P_HTML;
	  else
	    {
	      cpriv->buf[cpriv->buf_len++] = ch;
	      if (cpriv->buf_len == 5)
		{
		  if (strncasecmp (cpriv->buf, "data=", 5) == 0)
		    {
		      cpriv->state = P_LQUOTE;
		      cpriv->buf_len = 0;
		    }
		  else
		    {
		      memcpy (cpriv->buf, cpriv->buf + 1, 4);
		      cpriv->buf_len = 4;
		    }
		}
	    }
	  break;

	case P_LQUOTE:
	  if (ch == '"')
	    cpriv->state = P_QUOTED_URI;
	  else if (!isspace (ch))
	    {
	      cpriv->state = P_NAKED_URI;
	      cpriv->buf[cpriv->buf_len++] = ch;
	    }
	  break;

	case P_NAKED_URI:
	case P_QUOTED_URI:
	  if ((cpriv->state == P_QUOTED_URI && ch == '"')
	      || (cpriv->state == P_NAKED_URI && isspace (ch)))
	    {
	      cpriv->buf[cpriv->buf_len] = '\0';
	      fetch_uri (sess, priv, cpriv, cpriv->buf, cpriv->buf_len);
	      cpriv->state = P_HTML;
	      cpriv->buf_len = 0;
	    }
	  else if (cpriv->buf_len < sizeof (cpriv->buf) - 1)
	    cpriv->buf[cpriv->buf_len++] = ch;
	  break;
	}
    }
}