Beispiel #1
0
/** Parse http header response line 1 */
static err_t
http_parse_response_status(struct pbuf *p, u16_t *http_version, u16_t *http_status, u16_t *http_status_str_offset)
{
  u16_t end1 = pbuf_memfind(p, "\r\n", 2, 0);
  if (end1 != 0xFFFF) {
    /* get parts of first line */
    u16_t space1, space2;
    space1 = pbuf_memfind(p, " ", 1, 0);
    if (space1 != 0xFFFF) {
      if ((pbuf_memcmp(p, 0, "HTTP/", 5) == 0)  && (pbuf_get_at(p, 6) == '.')) {
        char status_num[10];
        size_t status_num_len;
        /* parse http version */
        u16_t version = pbuf_get_at(p, 5) - '0';
        version <<= 8;
        version |= pbuf_get_at(p, 7) - '0';
        *http_version = version;

        /* parse http status number */
        space2 = pbuf_memfind(p, " ", 1, space1 + 1);
        if (space2 != 0xFFFF) {
          *http_status_str_offset = space2 + 1;
          status_num_len = space2 - space1 - 1;
        } else {
          status_num_len = end1 - space1 - 1;
        }
        memset(status_num, 0, sizeof(status_num));
        if (pbuf_copy_partial(p, status_num, (u16_t)status_num_len, space1 + 1) == status_num_len) {
          int status = atoi(status_num);
          if ((status > 0) && (status <= 0xFFFF)) {
            *http_status = (u16_t)status;
            return ERR_OK;
          }
        }
      }
    }
  }
  return ERR_VAL;
}
Beispiel #2
0
/** Receive data on an iperf tcp session */
static err_t
lwiperf_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
  u16_t tot_len;
  u32_t packet_idx;
  struct pbuf* q;
  lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;

  LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb);
  LWIP_UNUSED_ARG(tpcb);

  if (err != ERR_OK) {
    lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
    return ERR_OK;
  }
  if (p == NULL) {
    /* connection closed -> test done */
    if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) ==
        PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) {
      /* client requested transmission after end of test */
      lwiperf_tx_start(conn);
    }
    lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_SERVER);
    return ERR_OK;
  }
  tot_len = p->tot_len;

  conn->poll_count = 0;

  if ((!conn->have_settings_buf) || ((conn->bytes_transferred -24) % (1024*128) == 0)) {
    /* wait for 24-byte header */
    if (p->tot_len < sizeof(lwiperf_settings_t)) {
      lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
      pbuf_free(p);
      return ERR_VAL;
    }
    if (!conn->have_settings_buf) {
      if (pbuf_copy_partial(p, &conn->settings, sizeof(lwiperf_settings_t), 0) != sizeof(lwiperf_settings_t)) {
        lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL);
        pbuf_free(p);
        return ERR_VAL;
      }
      conn->have_settings_buf = 1;
      if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) ==
        PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) {
          /* client requested parallel transmission test */
          err_t err2 = lwiperf_tx_start(conn);
          if (err2 != ERR_OK) {
            lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_TXERROR);
            pbuf_free(p);
            return err2;
          }
      }
    } else {
      if (pbuf_memcmp(p, 0, &conn->settings, sizeof(lwiperf_settings_t)) != 0) {
        lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
        pbuf_free(p);
        return ERR_VAL;
      }
    }
    conn->bytes_transferred += sizeof(lwiperf_settings_t);
    if(conn->bytes_transferred <= 24) {
      conn->time_started = sys_now();
      tcp_recved(tpcb, p->tot_len);
      pbuf_free(p);
      return ERR_OK;
    }
    conn->next_num = 4; /* 24 bytes received... */
    err = pbuf_header(p, -24);
    LWIP_ASSERT("pbuf_header failed", err == ERR_OK);
  }

  packet_idx = 0;
  for (q = p; q != NULL; q = q->next) {
#if LWIPERF_CHECK_RX_DATA
    const u8_t* payload = (const u8_t*)q->payload;
    u16_t i;
    for (i = 0; i < q->len; i++) {
      u8_t val = payload[i];
      u8_t num = val - '0';
      if (num == conn->next_num) {
        conn->next_num++;
        if (conn->next_num == 10) {
          conn->next_num = 0;
        }
      } else {
        lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
        pbuf_free(p);
        return ERR_VAL;
      }
    }
    packet_idx += i;
#else
    packet_idx += q->len;
#endif
  }
  LWIP_ASSERT("count mismatch", packet_idx == p->tot_len);
  conn->bytes_transferred += packet_idx;
  tcp_recved(tpcb, tot_len);
  pbuf_free(p);
  return ERR_OK;
}