/* Prepare to do a delegated send.  You want to try to call this out
 * of the critical path of sending or else you will not be getting
 * very much benefit from the API.
 *
 * In this app, we call this function right after having done the
 * previous send and while we wait for the next ping from the client.
 *
 * This function can be called speculatively.  If later on you decide that
 * you don't want to do a delegated send, you can call
 * zf_delegated_send_cancel().
 */
static void delegated_prepare(struct client_state* s)
{
  /* Prepare to do a delegated send: Tell the stack how much data we might
   * send, and retrieve the current packet headers.  In this sample
   * application we always send a message of length s->msg_len, but we pass
   * a larger value to zf_delegated_send_prepare() just to show that this
   * is supported.
   */
  s->zfds.headers = s->pkt_buf;
  s->zfds.headers_size = MAX_ETH_HEADERS + MAX_IP_TCP_HEADERS;
  enum zf_delegated_send_rc rc;
  rc = zf_delegated_send_prepare(s->tcp_sock, s->msg_len * 2, 0, 0, &(s->zfds));
  if( rc != ZF_DELEGATED_SEND_RC_OK ) {
    fprintf(stderr, "ERROR: zf_delegated_send_prepare: rc=%d\n", (int) rc);
    exit(3);
  }

  /* We've probably put the headers in the wrong place, because we've
   * allowed enough space for worst-case headers (including VLAN tag and
   * TCP options).  Move the headers up so that the end of the headers
   * meets the start of the message.
   */
  s->zfds.headers = s->msg_buf - s->zfds.headers_len;
  memmove(s->zfds.headers, s->pkt_buf, s->zfds.headers_len);

  /* If we want to send more than MSS (maximum segment size), we will have
   * to segment the message into multiple packets.  We do not handle that
   * case in this demo app.
   */
  int allowed_to_send = min(s->zfds.delegated_wnd, s->zfds.mss);

  if( s->msg_len <= allowed_to_send ) {
    s->pio_pkt_len = s->zfds.headers_len + s->msg_len;
    zf_delegated_send_tcp_update(&(s->zfds), s->msg_len, 1);
    TRY( ef_pio_memcpy(&(s->vi), s->zfds.headers, 0, s->pio_pkt_len) );
  }
  else {
    /* We can't do a delegated send at the moment, due to congestion window
     * or receive window being closed, or message size being larger than
     * the MSS.  Cancel the delegated send and use normal send instead.
     */
    TRY( zf_delegated_send_cancel(s->tcp_sock) );
    s->zfds.delegated_wnd = 0;
    s->pio_pkt_len = 0;
  }
}
示例#2
0
static void init_udp_pkt(void* pkt_buf, int paylen)
{
  int ip_len = sizeof(ci_ip4_hdr) + sizeof(ci_udp_hdr) + paylen;
  ci_ether_hdr* eth;
  ci_ip4_hdr* ip4;
  ci_udp_hdr* udp;

  eth = (ci_ether_hdr*)pkt_buf;
  ip4 = (void*) ((char*) eth + 14);
  udp = (void*) (ip4 + 1);
  /*payload = (void*) (udp + 1);*/

  memcpy(eth->ether_dhost, remote_mac, 6);
  ef_vi_get_mac(&vi, driver_handle, eth->ether_shost);
  eth->ether_type = htons(0x0800);
  ci_ip4_hdr_init(ip4, CI_NO_OPTS, ip_len, 0, IPPROTO_UDP,
		  sa_local.sin_addr.s_addr,
		  sa_remote.sin_addr.s_addr, 0);
  ci_udp_hdr_init(udp, ip4, sa_local.sin_port,
		  sa_remote.sin_port, udp + 1, paylen, 0);

  TRY(ef_pio_memcpy(&vi, pkt_buf, 0, ETH_HLEN + ip_len));
}