Example #1
0
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
 * free_mbuff_locking()									    *
 *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void free_mbuff_locking(struct mbuff *m)
{
    pthread_mutex_lock(&heap_mbuff_mutex);
    free_mbuff(m);
    pthread_mutex_unlock(&heap_mbuff_mutex);
    return;
}
Example #2
0
int
udp_Read (int sockid, caddr_t data, int size)
{
  int read;
  struct mbuff *mbuffer;
  udp_Socket *sock = (udp_Socket *) scheduler.sockets[sockid].ptr;

  if (sock->myport == 0)	/* minimal error checking */
    {
      SET_ERR (SCPS_EBADF);
      return (-1);
    }

  /* If there is no mbuff and associated data available, then we block */

  if (!(mbuffer = sock->receive_buff->start))
    {
      ((tp_Socket *) scheduler.sockets[sockid].ptr)->thread->status = Blocked;
      scheduler.num_runable--;
      scheduler.sockets[sockid].read = 1;
      sched ();
      mbuffer = sock->receive_buff->start;
    }

  /*
   * Make sure the size request is less than or equal 
   * to the amount of memory we have available to this connection
   */

  if (size > mbuffer->m_ext.len)
    size = mbuffer->m_ext.len;

  /*
   * At this point, it should just be a matter 
   * of doing a cb_cpdatout() into the data pointer...
   */

  read = cb_cpdatout (sock->app_rbuff, data, size);

#ifndef GATEWAY 
  if (!(sock->app_rbuff->size))
    sock->thread->read_socks &= ~(1 << sock->sockid);
#endif /* GATEWAY  */

  if (read == 0)
    {
      printf ("cb_cpdatout returns 0\t");
      printf ("size = %d, app rbuff size = %d\n", size, (int) sock->app_rbuff->size);
      SET_ERR (SCPS_EWOULDBLOCK);
      return (-1);
    }

  /* Trim off the associated mbuff from the receive-buffer.   */

  /*  mb_rtrim (sock->receive_buff, read); */
  mbuffer = deq_mbuff (sock->receive_buff);
  free_mbuff (mbuffer);
  return (read);
}
Example #3
0
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
 * alloc_mbuff_chain()									    *
 *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
size_t alloc_mbuff_chain( struct msg_queue *queue, size_t len)
{
    struct msg	 *p_buff;
    struct mbuff *m_buff;
    size_t i;
    /*
     * 1- Block mutex msg
     * 2- Block mutex mbuff
     * 3- Create n mbuff elements
     * 4- Create n pkbuff elements
     * 5- Unblock mutex mbuff
     * 6- Unblock mutex msg
     */
    pthread_mutex_lock(&heap_msg_mutex);
    pthread_mutex_lock(&heap_mbuff_mutex);

    for ( i = 0; i <= len-1 ; i++ ) {
	m_buff = alloc_mbuff();
	if (m_buff != NULL) {
	    p_buff = alloc_msg();
	    if (p_buff != NULL) {
		p_buff->p_next = NULL;
	        p_buff->mb.mbp = m_buff;
		msg_enqueue(queue, p_buff);
	    }
	    else {
		free_mbuff(m_buff);
		break;
	    }
	}
	else
	    break;
    }
    pthread_mutex_unlock(&heap_mbuff_mutex);
    pthread_mutex_unlock(&heap_msg_mutex);

    return i;
}
Example #4
0
/*
 * Try to send the UDP datagram. Enqueue at most 
 * one UDP datagram if there's room, and then try 
 * to send it. Return the number of bytes queued. 
 * Otherwise, throw away the data, return -1 and 
 * set EWOULDBLOCK for non-blocking, or just block.
 *
 * This will need to be modified to provide a way 
 * for the application to flush the one-datagram 
 * buffer. timer? "system call"? later
 */
int
udp_WriteTo (int sockid, byte * dp, int len, scps_np_addr ina, word port)
{
  uint32_t bytes_sent = 0;
#ifdef SCPSSP
  int temp;
#endif /* SCPSSP */
  int cc = 0;
  struct mbuff *mbuffer;
  struct mbcluster *mbcluster;
  udp_Socket *s = (udp_Socket *) scheduler.sockets[sockid].ptr;

  if (s->myport == 0)		/* minimal error checking */
    {
      SET_ERR (SCPS_EBADF);
      goto cleanup;
      return (-1);
    }

  if (len > MAX_UDP_PAYLOAD)	/* enforce max UDP datagram size ??????? */
    {
      SET_ERR (SCPS_EMSGSIZE);
      goto cleanup;
      return (-1);
    }

  if ((s->rt_route->MTU) &&	/* enforce MTU */
      ((len + UDP_HDR_LEN + s->np_size + s->sp_size) > s->rt_route->MTU))
    {
      SET_ERR (SCPS_EMSGSIZE);
      goto cleanup;
      return (-1);
    }
		
  if ((s->rt_route && s->rt_route->flags & RT_LINK_AVAIL) &&
      (s->rt_route->current_credit >=
       ((int) s->send_buff->start->m_ext.len +
	UDP_HDR_LEN + s->sp_size + 20)))	/* hard-coded for IP! */
    {
      s->buff_full = FALSE;
    }

  if (s->buff_full)
    {
      SET_ERR (SCPS_ENOBUFS);
      goto cleanup;
      return (-1);
    }

  if ((cb_cpdatin (s->app_sbuff, dp, len, 0, 0)) != len)
    {
      SET_ERR (SCPS_ENOBUFS);
      goto cleanup;
      return (-1);
    }
  s->ph.nl_head.ipv4.dst = ina;
  s->hisport = port;
  s->his_ipv4_addr = htonl ((uint32_t) ina);

  /* Build the packet! */

  if ((mcput (s->send_buff->start, s->app_sbuff->start,
	      s->app_sbuff->read_off, len, 1)) != len)
    {
      printf ("\nbigs problems in udp_WriteTo()\n");
      fflush (stdout);
      return (-1);
    }

  /* Fill in the requirements structure */
  s->np_rqts.tpid = SCPSUDP;
  s->np_rqts.ipv4_dst_addr = htonl (ina);
#ifdef UDP_GATEWAY
  s->np_rqts.ipv4_src_addr = s->my_ipv4_addr;
#else /* UDP_GATEWAY */
  s->np_rqts.ipv4_src_addr = ntohl (local_addr);
#endif /* UDP_GATEWAY */
  s->np_rqts.timestamp.format = 0;
  s->np_rqts.timestamp.ts_val[0] =
    s->np_rqts.timestamp.ts_val[1] = 0;
  /* s->np_rqts.bqos.precedence = rqts->bqos.precedence; */
  s->np_rqts.bqos.routing = 0;
  s->np_rqts.bqos.pro_specific = 0;
  s->np_rqts.eqos.ip_precedence = 0;
  s->np_rqts.eqos.ip_tos = 0;
  s->np_rqts.cksum = 0;
  s->np_rqts.int_del = 0;
  s->np_rqts.nl_protocol = nl_default;

#ifdef SCPSSP
  /* Fill in the SP requirements structure */
  s->sp_rqts.np_rqts.tpid = SP;
  s->sp_rqts.np_rqts.ipv4_dst_addr = htonl (ina);
#ifdef UDP_GATEWAY
  s->sp_rqts.np_rqts.ipv4_src_addr = s->myaddr;
#else /* UDP_GATEWAY */
  s->sp_rqts.np_rqts.ipv4_src_addr = ntohl (local_addr);
#endif /* UDP_GATEWAY */
  s->sp_rqts.np_rqts.timestamp.format = 0;
  s->sp_rqts.np_rqts.timestamp.ts_val[0] =
    s->sp_rqts.np_rqts.timestamp.ts_val[1] = 0;
  s->sp_rqts.np_rqts.bqos.precedence = 0;	/* rqts->bqos.precedence; */
  /* s->sp_rqts.np_rqts.bqos.routing = rqts->bqos.precedence; */
  s->sp_rqts.np_rqts.bqos.pro_specific = 0;
  s->sp_rqts.np_rqts.eqos.ip_precedence = 0;
  s->sp_rqts.np_rqts.eqos.ip_tos = 0;
  s->sp_rqts.np_rqts.cksum = 0;	/* rqts->cksum; */
  s->sp_rqts.np_rqts.int_del = 0;
  s->sp_rqts.np_rqts.nl_protocol = nl_default;
  s->sp_rqts.tpid = SCPSUDP;
  s->sp_rqts.sprqts = 0;
  s->np_rqts.tpid = SP;
#ifdef SECURE_GATEWAY
  s->sp_rqts.secure_gateway_rqts = s->rt_route->secure_gateway_rqts;
#endif /* SECURE_GATEWAY */
  s->sp_size = sp_hdr_size (s->sp_rqts);
  temp = s->sp_size + (s->sp_size % sizeof (uint32_t));
  s->sh_off = s->th_off - temp;
#endif /* SCPSSP */

  switch (s->np_rqts.nl_protocol) { 
	case NL_PROTOCOL_IPV4:
		s->np_size = ip_get_template (&(s->np_rqts), &(s->ip_templ));
		break;

	case NL_PROTOCOL_NP:
		s->np_size = scps_np_get_template (&(s->np_rqts), &(s->np_templ));
		break;
  }

  udp_BuildHdr (s, s->send_buff->start);

  s->app_sbuff->size -= len;	/* size should be zero now! */
  s->buff_full = TRUE;

  if ((s->rt_route && s->rt_route->flags & RT_LINK_AVAIL) &&
      (s->rt_route->current_credit >=
       ((int) s->send_buff->start->m_ext.len +
	UDP_HDR_LEN + s->sp_size + 20)))	/* hard-coded for IP! */
    {
      cc = udp_Coalesce (s, &bytes_sent);
      bytes_sent = len;
      s->buff_full = FALSE;
      /* Let them know how much data we actually wrote to the transport */
      if (cc > 0)
	s->user_data += len;
    }

cleanup:

  /*
     * This all looks kind of crusty 
   */
  /* dequeue all clusters */
  for (mbcluster = deq_mclus (s->app_sbuff); mbcluster;
       mbcluster = deq_mclus (s->app_sbuff))
    free_mclus (mbcluster);

  s->app_sbuff->read_head = s->app_sbuff->write_head = NULL;
  s->app_sbuff->write_off = s->app_sbuff->bytes_beyond = 0;
  mbuffer = deq_mbuff (s->send_buff);
  free_mbuff (mbuffer);		/* free mbuff and all clusters */

  if (!(mbuffer = alloc_mbuff (MT_HEADER)))	/* get back our mbuff */
    {
      SET_ERR (SCPS_ENOMEM);
      exit (-1);		/* not the thing to do */
    }
  if (!(enq_mbuff (mbuffer, s->send_buff)))
    printf ("MBUFFER ENQUEUEING ERROR in udp_Coalesce()\n");
  if (cc)
    return (len);
  else
    {
      SET_ERR (SCPS_ENOBUFS);
      return (-1);
    }
}