Exemplo n.º 1
0
int
soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
{
	KASSERT(so->so_pcb == NULL || solocked(so));

	/*
	 * there's at least one application (a configure script of screen)
	 * which expects a fifo is writable even if it has "some" bytes
	 * in its buffer.
	 * so we want to make sure (hiwat - lowat) >= (some bytes).
	 *
	 * PIPE_BUF here is an arbitrary value chosen as (some bytes) above.
	 * we expect it's large enough for such applications.
	 */
	u_long  lowat = MAX(sock_loan_thresh, MCLBYTES);
	u_long  hiwat = lowat + PIPE_BUF;

	if (sndcc < hiwat)
		sndcc = hiwat;
	if (sbreserve(&so->so_snd, sndcc, so) == 0)
		goto bad;
	if (sbreserve(&so->so_rcv, rcvcc, so) == 0)
		goto bad2;
	if (so->so_rcv.sb_lowat == 0)
		so->so_rcv.sb_lowat = 1;
	if (so->so_snd.sb_lowat == 0)
		so->so_snd.sb_lowat = lowat;
	if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
		so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
	return (0);
 bad2:
	sbrelease(&so->so_snd, so);
 bad:
	return (ENOBUFS);
}
Exemplo n.º 2
0
/* FUNCTION: sorflush()
 * 
 * PARAM1: struct socket *    socket structure
 *
 * RETURNS: none
 *
 * Closes the "read" half of the socket connection. No more data
 * can be received on the socket, and any data currently in the 
 * socket receive buffer is discarded. Wakeup any processes waiting
 * on the socket.
 */
void
sorflush(struct socket * so)
{
   struct sockbuf *sb =  &so->so_rcv;
   int   s;

   sblock(sb);
   socantrcvmore(so);
   sbunlock(sb);
   sbrelease(sb);
   MEMSET((char *)sb, 0, sizeof (*sb));
   s = so->so_error;
   so->so_error = ESHUTDOWN;
   sorwakeup(so);
   so->so_error = s;
}
Exemplo n.º 3
0
/*
 * Socket buffer (struct sockbuf) utility routines.
 *
 * Each socket contains two socket buffers: one for sending data and
 * one for receiving data.  Each buffer contains a queue of mbufs,
 * information about the number of mbufs and amount of data in the
 * queue, and other fields allowing select() statements and notification
 * on data availability to be implemented.
 *
 * Data stored in a socket buffer is maintained as a list of records.
 * Each record is a list of mbufs chained together with the m_next
 * field.  Records are chained together with the m_nextpkt field. The upper
 * level routine soreceive() expects the following conventions to be
 * observed when placing information in the receive buffer:
 *
 * 1. If the protocol requires each message be preceded by the sender's
 *    name, then a record containing that name must be present before
 *    any associated data (mbuf's must be of type MT_SONAME).
 * 2. If the protocol supports the exchange of ``access rights'' (really
 *    just additional data associated with the message), and there are
 *    ``rights'' to be received, then a record containing this data
 *    should be present (mbuf's must be of type MT_RIGHTS).
 * 3. If a name or rights record exists, then it must be followed by
 *    a data record, perhaps of zero length.
 *
 * Before using a new socket structure it is first necessary to reserve
 * buffer space to the socket, by calling sbreserve().  This should commit
 * some of the available buffer space in the system buffer pool for the
 * socket (currently, it does nothing but enforce limits).  The space
 * should be released by calling sbrelease() when the socket is destroyed.
 */
int
soreserve(struct usn_socket *so, u_long sndcc, u_long rcvcc)
{

   if (sbreserve(&so->so_snd, sndcc) == 0)
      goto bad;
   if (sbreserve(&so->so_rcv, rcvcc) == 0)
      goto bad2;
   if (so->so_rcv.sb_lowat == 0)
      so->so_rcv.sb_lowat = 1;
   if (so->so_snd.sb_lowat == 0)
      so->so_snd.sb_lowat = MCLBYTES;
   if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
      so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
   return (0);
bad2:
   sbrelease(&so->so_snd);
bad:
   return -1;// no buffer available: (ENOBUFS);
}
Exemplo n.º 4
0
void
sofree(struct socket * so)
{
   INET_TRACE (INETM_SOCKET|INETM_CLOSE,
    ("INET: sofree, so %lx so_pcb %lx so_state %x so_head %lx\n",
    so, so->so_pcb, so->so_state, so->so_head));

   if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
      return;
   if (so->so_head) 
   {
      if (!soqremque(so, 0) && !soqremque(so, 1))
         panic("sofree");
      so->so_head = 0;
   }
   sbrelease(&so->so_snd);
   sorflush(so);
#ifdef SAVE_SOCK_ENDPOINTS
   if (so->so_endpoint)
      _socket_free_entry (so);
#endif   /* SAVE_SOCK_ENDPOINTS */

#ifdef IP_MULTICAST
   /* multicast opts? */
   if (so->inp_moptions)
	   ip_freemoptions(so->inp_moptions);
#endif   /* IP_MULTICAST */

   /* IP_TOS opts? */
   if (so->so_optsPack)
      SOCOPT_FREE(so->so_optsPack);
	   
   qdel(&soq, so);   /* Delete the socket entry from the queue */
   
   if (so_evtmap)  
      (*so_evtmap_delete) (so);
   
   SOC_FREE(so);
}
Exemplo n.º 5
0
int
soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
{

	if (sbreserve(&so->so_snd, sndcc))
		goto bad;
	if (sbreserve(&so->so_rcv, rcvcc))
		goto bad2;
	so->so_snd.sb_wat = sndcc;
	so->so_rcv.sb_wat = rcvcc;
	if (so->so_rcv.sb_lowat == 0)
		so->so_rcv.sb_lowat = 1;
	if (so->so_snd.sb_lowat == 0)
		so->so_snd.sb_lowat = MCLBYTES;
	if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
		so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
	return (0);
bad2:
	sbrelease(&so->so_snd);
bad:
	return (ENOBUFS);
}