Exemplo n.º 1
0
int
tcp_rcv(PACKET pkt)     /* NOTE: pkt has nb_prot pointing to IP header */
{
   struct mbuf *  m_in;
   struct ip * bip;  /* IP header, berkeley version */
   struct tcphdr *   tcpp;
   unshort  len;  /* scratch length holder */

   /* For TCP, the netport IP layer is modified to set nb_prot to the 
    * start of the IP header (not TCP). We need to do some further
    * mods which the BSD code expects:
    */
   bip = (struct ip *)pkt->nb_prot;    /* get ip header */
   len = ntohs(bip->ip_len);  /* get length in local endian */

   /* verify checksum of received packet */

   tcpp = (struct tcphdr *)ip_data(bip);
   if (tcp_cksum(bip) != tcpp->th_sum)
   {
      TCP_MIB_INC(tcpInErrs);    /* keep MIB stats */
      tcpstat.tcps_rcvbadsum++;  /* keep BSD stats */
      LOCK_NET_RESOURCE(FREEQ_RESID);
      pk_free(pkt);  /* punt packet */
      UNLOCK_NET_RESOURCE(FREEQ_RESID);
      return ENP_BAD_HEADER;
   }

   m_in = m_getnbuf(MT_RXDATA, 0);
   if (!m_in){
      LOCK_NET_RESOURCE(FREEQ_RESID);
      pk_free(pkt);
      UNLOCK_NET_RESOURCE(FREEQ_RESID);
      return ENP_RESOURCE;  
   }

   IN_PROFILER(PF_TCP, PF_ENTRY);      /* measure time in TCP */

   /* subtract IP header length from total IP packet length */
   len -= ((unshort)(bip->ip_ver_ihl & 0x0f) << 2);
   bip->ip_len = len;   /* put TCP length in struct for TCP code to use */

   /* set mbuf to point to start of IP header (not TCP) */
   m_in->pkt = pkt;
   m_in->m_data = pkt->nb_prot;
   m_in->m_len = pkt->nb_plen;
   m_in->m_base = pkt->nb_buff;     /* ??? */
   m_in->m_memsz = pkt->nb_blen;    /* ??? */

   tcp_input(m_in, pkt->net);

   IN_PROFILER(PF_TCP, PF_EXIT);      /* measure time in TCP */

   return 0;
}
Exemplo n.º 2
0
int
t_recv (long s, 
   char *   buf,
   int   len, 
   int   flag)
{
#ifdef SOCKDEBUG
   char logbuf[10];
#endif
   struct socket *   so;
   int   err;
   int   sendlen = len;

   so = LONG2SO(s);
#ifdef SOC_CHECK_ALWAYS
   SOC_CHECK(so);
#endif
   if ((so->so_state & SO_IO_OK) != SS_ISCONNECTED)
   {
      so->so_error = EPIPE;
#ifdef SOCKDEBUG
      sprintf(logbuf, "t_recv: %d", so->so_error);
      glog_with_type(LOG_TYPE_DEBUG, logbuf, 1);
#endif
      return SOCKET_ERROR;
   }
   so->so_error = 0;

   LOCK_NET_RESOURCE(NET_RESID);
   IN_PROFILER(PF_TCP, PF_ENTRY);        /* measure time in TCP */
   INET_TRACE (INETM_IO, ("INET:recv: so %x, len %d\n", so, len));
   err = soreceive(so, NULL, buf, &len, flag);
   IN_PROFILER(PF_TCP, PF_EXIT);        /* measure time in TCP */
   UNLOCK_NET_RESOURCE(NET_RESID);

   if(err)
   {
      so->so_error = err;
#ifdef SOCKDEBUG
      sprintf(logbuf, "t_recv: %d", so->so_error);
      glog_with_type(LOG_TYPE_DEBUG, logbuf, 1);
#endif
      return SOCKET_ERROR;
   }

   /* return bytes we sent - the amount we wanted to send minus
    * the amount left in the buffer.
    */
   return (sendlen - len);
}
Exemplo n.º 3
0
void
tk_block () 
{
   char msg[255];
   task * tk = tk_cur;     /* the next task to run */

   /* check if the guard word is still intact */
   if (*(tk->tk_guard) != GUARDWORD)
   {
      sprintf(msg, "tk_block stack: task name = %s", tk->tk_name);
      panic(msg);
      return;
   }

#ifdef NPDEBUG
   if (TDEBUG)
      dprintf("TASK: Task %s blocking.\n", tk->tk_name);
#endif

   IN_PROFILER(PF_IDLE, PF_ENTRY);      /* measure time in the idle loop */

   /* find the next ready to run task */
   do 
   {
      tk = tk->tk_next;
      /* see if a sleeping task is ready to wake */
      if (tk->tk_waketick && tk->tk_waketick < cticks)
      {
         tk->tk_waketick = 0; /* clear wakeup tick flag */
         break;   /* go run this task */
      }
   } while ((tk->tk_flags & TF_AWAKE) == 0);

   IN_PROFILER(PF_IDLE, PF_EXIT);

   tk->tk_flags &= ~TF_AWAKE;    /* clear wake flag before it runs */
   tk_switch (tk);      /* Run the next task. */

#ifdef NPDEBUG
   if (TDEBUG)
      dprintf("TASK: Task %s running\n", tk_cur->tk_name);
#endif

   if (tk_died) 
   {
      tk_del(tk_died);  /* delete dead task */
      tk_died = NULL;   /* clear pointer/flag */
   }
}
Exemplo n.º 4
0
int
t_send(long s, 
   char *   buf,
   int      len, 
   int      flags)
{
   struct socket *   so;
   int   e;       /* error holder */
   int   total_sent  =  0;
   int   maxpkt;
   int   sendlen;
   int   sent;

   so = LONG2SO(s);
#ifdef SOC_CHECK_ALWAYS
   SOC_CHECK(so);
#endif
   if ((so->so_state & SO_IO_OK) != SS_ISCONNECTED)
   {
      so->so_error = EPIPE;
      return SOCKET_ERROR;
   }
   so->so_error = 0;

   /* If this is not a stream socket, assume it is bound and pass to
    * t_sendto() with a null sockaddr
    */
   if (so->so_type != SOCK_STREAM)
      return(t_sendto(s, buf, len, flags, NULL, 0));

   maxpkt = TCP_MSS;
   if(so->so_pcb)
   { 
      struct tcpcb * tp;
      tp = intotcpcb(so->so_pcb);   /* get tcp structure with mss */
      if(tp->t_maxseg)              /* Make sure it's set */
         maxpkt = tp->t_maxseg;
   }

   IN_PROFILER(PF_TCP, PF_ENTRY);       /* measure time in TCP */

   while (len)
   {
      if (len > maxpkt)
         sendlen = maxpkt;  /* take biggest block we can */
      else
         sendlen = len;
      sent = sendlen;

      LOCK_NET_RESOURCE(NET_RESID);
      e = sosend (so, NULL, buf, &sendlen, flags);
      UNLOCK_NET_RESOURCE(NET_RESID);
 
      if (e != 0)  /* sock_sendit failed? */
      {
         /* if we simply ran out of bufs, report back to caller. */
         if ((e == ENOBUFS) || (e == EWOULDBLOCK))
         {
            /* if we actually sent something before running out
             * of buffers, report what we sent; 
             * else, report the error and let the application 
             * retry the call later
             */
            if (total_sent != 0)
            {
               so->so_error = 0;
               break;      /* break out of while(len) loop */
            }
         }
         so->so_error = e;
         return SOCKET_ERROR;
      }
      /* if we can't send anymore, return now */
      if (sendlen != 0)
         break;         /* break out of while(len) loop */

      /* adjust numbers & pointers, and go do next send loop */
      sent -= sendlen;        /* subtract anything that didn't get sent */
      buf += sent;
      len -= sent;
      total_sent += sent;
   }

   IN_PROFILER(PF_TCP, PF_EXIT);        /* measure time in TCP */
   return total_sent;
}
Exemplo n.º 5
0
/* FUNCTION: tk_block()
 *
 * Block the currently running task and run the next task in the 
 * circular list of tasks that is awake. Before returning, see if any 
 * cleanup has to be done for another task. 
 * 
 * PARAMS: task *             pointer to currently executing task or NULL
 *
 * RETURN: none
 */
void
tk_block(TASK *tk_old) 
{
   TASK *tk, *tk_prev;

   /* check the stack of the currently executing task for overflow */
   if (tk_old != (TASK *)NULL)
   {
      /* check if the guard word is still intact */
      if (*(tk_cur->tk_guard) != GUARDWORD)
      {
         dprintf("tk_block stack: task name = %s", tk_cur->tk_name);
         dtrap();
         return;
      }
   }

#ifdef NPDEBUG
   if (TDEBUG)
      dprintf("TASK: Task %s blocking.\n", tk_cur->tk_name);
#endif

   IN_PROFILER(PF_IDLE, PF_ENTRY);      /* measure time in the idle loop */

   /* find the next ready to run task */
   tk = tk_cur;
#ifdef DEBUG_TASK_STATE
   dprintf("tk_block: %s, flags = %lx, event = %p\n",
            tk->tk_name, tk->tk_flags, tk->tk_event);
#endif
   do 
   {
      tk_prev = tk;
      tk = tk->tk_next;
      /* TODO: check for deleted task here */
         
      /* see if a sleeping task is ready to wake */
      if ((tk->tk_flags & TF_TIMER) && TIME_EXP(tk->tk_waketick, CTICKS))
      {
         tk_timeout(tk);      /* clean up after timeout */
      }
   } while (!(tk->tk_flags & TF_AWAKE));

   IN_PROFILER(PF_IDLE, PF_EXIT);

   tk->tk_count++;         /* increment wakeup count */
   tk_cur = tk;            /* update current task pointer */

#ifdef NPDEBUG
   if (TDEBUG)
      dprintf("TASK: Task %s running\n", tk->tk_name);
#endif
#ifdef DEBUG_TASK_STATE
   dprintf("tk_ready: %s, flags = %lx, event = %p\n",
            tk->tk_name, tk->tk_flags, tk->tk_event);
#endif

   tk_switch (tk, tk_old);      /* Run the next task. */

   if (tk_died) 
   {
      tk_del(tk_died);  /* delete dead task */
      tk_died = NULL;   /* clear pointer/flag */
   }
}