Beispiel #1
0
static VALUE t_add(VALUE self, VALUE obj) {
  Clist *array;
  VALUE arrayv = rb_iv_get(self, "@clist");
  Data_Get_Struct(arrayv, Clist, array);
  clist_add(array, (void*)obj);
  return Qnil;
}
Beispiel #2
0
void speech_trimmer_enqueue(SpeechTrimmer *self, Carr* pcm) {
  if (self->eos_reached) {
    carr_free(pcm);
    return;
  }
  clist_add(self->queue, pcm);
  if (bent_cent_marker_apply(self->bcm, pcm)) {
    self->false_count = 0;
    self->true_count += 1;
  } else {
    self->false_count += 1;
    self->true_count = 0;
  }
  if (self->speech_started) {
    if (self->false_count == self->ecs) {
      self->eos_reached = TRUE;
      int new_size = clist_size(self->queue) - self->ecs + self->trailer;
      int i;
      for (i=new_size; i<clist_size(self->queue); ++i)
        carr_free(clist_get(self->queue, i));

      clist_remove(self->queue, new_size, clist_size(self->queue));
    }
  } else if (self->true_count > self->scs) {
    if (self->leader + self->scs < clist_size(self->queue)) {
      int start = clist_size(self->queue) - self->leader - self->scs - 1;
      int i;
      for (i=0; i<start; ++i)
        carr_free(clist_get(self->queue, i));

      clist_remove(self->queue, 0, start);
    }
    self->speech_started = TRUE;
  }
}
Beispiel #3
0
static void test_clist_add_one(void)
{
    clist_node_t *list = NULL, *elem = &(tests_clist_buf[0]);

    clist_add(&list, elem);

    TEST_ASSERT_NOT_NULL(list);
    TEST_ASSERT(list->next == list);
}
Beispiel #4
0
/*
 * e_rnode_add
 *
 * adds an external node in the ext_rnode_cache list.
 */
void
e_rnode_add(ext_rnode_cache ** erc, ext_rnode * e_rnode, int rnode_pos,
			u_int * counter)
{
	ext_rnode_cache *p;

	p = xzalloc(sizeof(ext_rnode_cache));
	p->e = e_rnode;
	p->rnode_pos = rnode_pos;

	clist_add(erc, counter, p);
}
Beispiel #5
0
/*
 * rnl_add
 *
 * adds a new rnode_list struct in the `*rnlist' list. The new
 * allocated struct will be filled respectively with `rnode' and `dev'.
 * It returns the added `rnode_list' struct.
 */
struct rnode_list *
rnl_add(struct rnode_list **rnlist, int *rnlist_counter,
        map_node * rnode, interface * dev)
{
    struct rnode_list *rnl;

    rnl = xzalloc(sizeof(struct rnode_list));
    rnl->node = (map_node *) rnode;
    rnl->dev[0] = dev;
    rnl->dev_n++;

    clist_add(rnlist, rnlist_counter, rnl);

    return rnl;
}
Beispiel #6
0
void sched_set_status(tcb_t *process, unsigned int status) {
    if (status &  STATUS_ON_RUNQUEUE) {
        if (! (process->status &  STATUS_ON_RUNQUEUE)) {
            DEBUG("adding process %s to runqueue %u.\n", process->name, process->priority);
            clist_add(&runqueues[process->priority], &(process->rq_entry));
            runqueue_bitcache |= 1 << process->priority;
        }
    } else {
        if (process->status & STATUS_ON_RUNQUEUE) {
            DEBUG("removing process %s from runqueue %u.\n", process->name, process->priority);
            clist_remove(&runqueues[process->priority], &(process->rq_entry));
            if (! runqueues[process->priority] ) {
                runqueue_bitcache &= ~(1 << process->priority);
            }
        }
    }
    process->status = status;
}
Beispiel #7
0
/*
 * igw_add_node: adds a new gw in the `igws[`level']' llist.
 * The pointer to the new inet_gw is returned.
 */
inet_gw *
igw_add_node(inet_gw ** igws, int *igws_counter, int level,
			 int gid, map_node * node, int ip[MAX_IP_INT],
			 u_char bandwidth)
{
	inet_gw *igw;

	node->flags |= MAP_IGW;

	igw = xzalloc(sizeof(inet_gw));
	memcpy(igw->ip, ip, MAX_IP_SZ);
	igw->node = node;
	igw->gid = gid;
	igw->bandwidth = bandwidth;

	clist_add(&igws[level], &igws_counter[level], igw);

	return igw;
}
Beispiel #8
0
/*
 * new_rnode_allowed
 *
 * add a new allowed rnode in the `alr' llist which has
 * already `*alr_counter' members. `gid', `min_lvl', and `tot_lvl' are the
 * respective field of the new allowed_rnode struct.
 */
void
new_rnode_allowed(struct allowed_rnode **alr, int *alr_counter,
                  int *gid, int min_lvl, int tot_lvl)
{
    struct allowed_rnode *new_alr;

    new_alr = xmalloc(sizeof(struct allowed_rnode));

    new_alr->min_level = min_lvl;
    new_alr->tot_level = tot_lvl;

    setzero(new_alr->gid, sizeof(int) * MAX_LEVELS);
    memcpy(&new_alr->gid[min_lvl], &gid[min_lvl],
           sizeof(int) * (tot_lvl - min_lvl));

    debug(DBG_SOFT,
          "new_rnode_allowed: %d, %d, %d, %d. min_lvl: %d, tot_lvl: %d",
          gid[0], gid[1], gid[2], gid[3], min_lvl, tot_lvl);

    clist_add(alr, alr_counter, new_alr);
}
Beispiel #9
0
Cmat * speech_trimmer_apply(SpeechTrimmer *self, Carr* pcm) {
  if (self->eos_reached)
    return NULL;

  Cmat *segment_matrix = segmenter_apply(self->seg, pcm);
  if (segment_matrix == NULL)
	  return NULL;

  Clist *speech_segments = clist_new();
  int centisecond_count = segment_matrix->rows;
  Carr **segments = mat2arrs(segment_matrix);
  int speech_count = 0, i;
  for (i=0; i<centisecond_count ;++i) {
    speech_trimmer_enqueue(self, segments[i]);
    Carr *centispeech = speech_trimmer_dequeue(self);
    while (centispeech != NULL) {
      clist_add(speech_segments, centispeech);
      speech_count++;
      centispeech = speech_trimmer_dequeue(self);
    }
    if (speech_trimmer_eos(self)) {
      for (i+=1;i<centisecond_count; ++i)
        carr_free(segments[i]);
      break;
    }
  }
  free(segments);

  if (speech_trimmer_eos(self) && speech_count == 0) {
    for (i=0; i<clist_size(speech_segments); ++i)
      carr_free(clist_get(speech_segments, i));

    clist_free(speech_segments);
    return NULL;
  }

  Cmat *result = arrs2mat((Carr**)speech_segments->data, speech_count);
  free(speech_segments);
  return result;
}
Beispiel #10
0
int net_if_add_address(int if_id, net_if_addr_t *addr)
{
    if (!addr || !addr->addr_data) {
        DEBUG("Address addition: Precondition not met.\n");
        return 0;
    }

    if (if_id < 0 || if_id >= NET_IF_MAX || !interfaces[if_id].initialized) {
        DEBUG("Address addition: No interface initialized with ID %d.\n", if_id);
        return 0;
    }

    mutex_lock(&interfaces[if_id].address_buffer_mutex);

    interfaces[if_id].protocols |= addr->addr_protocol;

    clist_add((clist_node_t **)&interfaces[if_id].addresses,
              (clist_node_t *)addr);

    mutex_unlock(&interfaces[if_id].address_buffer_mutex);

    return 1;
}
Beispiel #11
0
void sched_set_status(thread_t *process, unsigned int status)
{
    if (status >= STATUS_ON_RUNQUEUE) {
        if (!(process->status >= STATUS_ON_RUNQUEUE)) {
            DEBUG("sched_set_status: adding thread %" PRIkernel_pid " to runqueue %" PRIu16 ".\n",
                  process->pid, process->priority);
            clist_add(&sched_runqueues[process->priority], &(process->rq_entry));
            runqueue_bitcache |= 1 << process->priority;
        }
    }
    else {
        if (process->status >= STATUS_ON_RUNQUEUE) {
            DEBUG("sched_set_status: removing thread %" PRIkernel_pid " to runqueue %" PRIu16 ".\n",
                  process->pid, process->priority);
            clist_remove(&sched_runqueues[process->priority], &(process->rq_entry));

            if (!sched_runqueues[process->priority]) {
                runqueue_bitcache &= ~(1 << process->priority);
            }
        }
    }

    process->status = status;
}
Beispiel #12
0
static void test_netdev_dummy_send_data_with_ulhs(void)
{
    netdev_hlist_t hlist_node = {NULL, NULL, NETDEV_PROTO_UNKNOWN, TEST_STRING8, 4};
    netdev_hlist_t *hlist = NULL;
    char dest[] = TEST_STRING64;
    size_t dest_len = UNITTESTS_NETDEV_DUMMY_MAX_ADDR_LEN;
    char data[] = TEST_STRING16;
#if UNITTESTS_NETDEV_DUMMY_MAX_PACKET < 12
    size_t data_len = UNITTESTS_NETDEV_DUMMY_MAX_PACKET - 4;
    char expected[UNITTESTS_NETDEV_DUMMY_MAX_PACKET];
#else
    size_t data_len = 8;
    char expected[12];
#endif

    memcpy(expected, TEST_STRING8, 4);
    memcpy(&(expected[4]), TEST_STRING16, data_len);

    clist_add((clist_node_t **)&hlist, (clist_node_t *)&hlist_node);
    TEST_ASSERT_EQUAL_INT((int)sizeof(expected), dev->driver->send_data(dev,
                          dest, dest_len, hlist, data, data_len));
    TEST_ASSERT_EQUAL_INT(0, unittest_netdev_dummy_check_transmitted(dev,
                          dest, dest_len, expected, data_len + 4));
}
/* ARGSUSED */
static enum clnt_stat
clnt_rdma_kcallit(CLIENT *h, rpcproc_t procnum, xdrproc_t xdr_args,
    caddr_t argsp, xdrproc_t xdr_results, caddr_t resultsp,
    struct timeval wait)
{
	cku_private_t *p = htop(h);

	int 	try_call_again;
	int	refresh_attempt = AUTH_REFRESH_COUNT;
	int 	status;
	int 	msglen;

	XDR	*call_xdrp, callxdr; /* for xdrrdma encoding the RPC call */
	XDR	*reply_xdrp, replyxdr; /* for xdrrdma decoding the RPC reply */
	XDR 	*rdmahdr_o_xdrs, *rdmahdr_i_xdrs;

	struct rpc_msg 	reply_msg;
	rdma_registry_t	*m;

	struct clist *cl_sendlist;
	struct clist *cl_recvlist;
	struct clist *cl;
	struct clist *cl_rpcmsg;
	struct clist *cl_rdma_reply;
	struct clist *cl_rpcreply_wlist;
	struct clist *cl_long_reply;
	rdma_buf_t  rndup;

	uint_t vers;
	uint_t op;
	uint_t off;
	uint32_t seg_array_len;
	uint_t long_reply_len;
	uint_t rpcsec_gss;
	uint_t gss_i_or_p;

	CONN *conn = NULL;
	rdma_buf_t clmsg;
	rdma_buf_t rpcmsg;
	rdma_chunkinfo_lengths_t rcil;

	clock_t	ticks;
	bool_t wlist_exists_reply;

	uint32_t rdma_credit = rdma_bufs_rqst;

	RCSTAT_INCR(rccalls);

call_again:

	bzero(&clmsg, sizeof (clmsg));
	bzero(&rpcmsg, sizeof (rpcmsg));
	bzero(&rndup, sizeof (rndup));
	try_call_again = 0;
	cl_sendlist = NULL;
	cl_recvlist = NULL;
	cl = NULL;
	cl_rpcmsg = NULL;
	cl_rdma_reply = NULL;
	call_xdrp = NULL;
	reply_xdrp = NULL;
	wlist_exists_reply  = FALSE;
	cl_rpcreply_wlist = NULL;
	cl_long_reply = NULL;
	rcil.rcil_len = 0;
	rcil.rcil_len_alt = 0;
	long_reply_len = 0;

	rw_enter(&rdma_lock, RW_READER);
	m = (rdma_registry_t *)p->cku_rd_handle;
	if (m->r_mod_state == RDMA_MOD_INACTIVE) {
		/*
		 * If we didn't find a matching RDMA module in the registry
		 * then there is no transport.
		 */
		rw_exit(&rdma_lock);
		p->cku_err.re_status = RPC_CANTSEND;
		p->cku_err.re_errno = EIO;
		ticks = clnt_rdma_min_delay * drv_usectohz(1000000);
		if (h->cl_nosignal == TRUE) {
			delay(ticks);
		} else {
			if (delay_sig(ticks) == EINTR) {
				p->cku_err.re_status = RPC_INTR;
				p->cku_err.re_errno = EINTR;
			}
		}
		return (RPC_CANTSEND);
	}
	/*
	 * Get unique xid
	 */
	if (p->cku_xid == 0)
		p->cku_xid = alloc_xid();

	status = RDMA_GET_CONN(p->cku_rd_mod->rdma_ops, &p->cku_srcaddr,
	    &p->cku_addr, p->cku_addrfmly, p->cku_rd_handle, &conn);
	rw_exit(&rdma_lock);

	/*
	 * If there is a problem with the connection reflect the issue
	 * back to the higher level to address, we MAY delay for a short
	 * period so that we are kind to the transport.
	 */
	if (conn == NULL) {
		/*
		 * Connect failed to server. Could be because of one
		 * of several things. In some cases we don't want
		 * the caller to retry immediately - delay before
		 * returning to caller.
		 */
		switch (status) {
		case RDMA_TIMEDOUT:
			/*
			 * Already timed out. No need to delay
			 * some more.
			 */
			p->cku_err.re_status = RPC_TIMEDOUT;
			p->cku_err.re_errno = ETIMEDOUT;
			break;
		case RDMA_INTR:
			/*
			 * Failed because of an signal. Very likely
			 * the caller will not retry.
			 */
			p->cku_err.re_status = RPC_INTR;
			p->cku_err.re_errno = EINTR;
			break;
		default:
			/*
			 * All other failures - server down or service
			 * down or temporary resource failure. Delay before
			 * returning to caller.
			 */
			ticks = clnt_rdma_min_delay * drv_usectohz(1000000);
			p->cku_err.re_status = RPC_CANTCONNECT;
			p->cku_err.re_errno = EIO;

			if (h->cl_nosignal == TRUE) {
				delay(ticks);
			} else {
				if (delay_sig(ticks) == EINTR) {
					p->cku_err.re_status = RPC_INTR;
					p->cku_err.re_errno = EINTR;
				}
			}
			break;
		}

		return (p->cku_err.re_status);
	}

	if (p->cku_srcaddr.maxlen < conn->c_laddr.len) {
		if ((p->cku_srcaddr.maxlen != 0) &&
		    (p->cku_srcaddr.buf != NULL))
			kmem_free(p->cku_srcaddr.buf, p->cku_srcaddr.maxlen);
		p->cku_srcaddr.buf = kmem_zalloc(conn->c_laddr.maxlen,
		    KM_SLEEP);
		p->cku_srcaddr.maxlen = conn->c_laddr.maxlen;
	}

	p->cku_srcaddr.len = conn->c_laddr.len;
	bcopy(conn->c_laddr.buf, p->cku_srcaddr.buf, conn->c_laddr.len);

	clnt_check_credit(conn);

	status = CLNT_RDMA_FAIL;

	rpcsec_gss = gss_i_or_p = FALSE;

	if (IS_RPCSEC_GSS(h)) {
		rpcsec_gss = TRUE;
		if (rpc_gss_get_service_type(h->cl_auth) ==
		    rpc_gss_svc_integrity ||
		    rpc_gss_get_service_type(h->cl_auth) ==
		    rpc_gss_svc_privacy)
			gss_i_or_p = TRUE;
	}

	/*
	 * Try a regular RDMA message if RPCSEC_GSS is not being used
	 * or if RPCSEC_GSS is being used for authentication only.
	 */
	if (rpcsec_gss == FALSE ||
	    (rpcsec_gss == TRUE && gss_i_or_p == FALSE)) {
		/*
		 * Grab a send buffer for the request.  Try to
		 * encode it to see if it fits. If not, then it
		 * needs to be sent in a chunk.
		 */
		rpcmsg.type = SEND_BUFFER;
		if (rdma_buf_alloc(conn, &rpcmsg)) {
			DTRACE_PROBE(krpc__e__clntrdma__callit_nobufs);
			goto done;
		}

		/* First try to encode into regular send buffer */
		op = RDMA_MSG;

		call_xdrp = &callxdr;

		xdrrdma_create(call_xdrp, rpcmsg.addr, rpcmsg.len,
		    rdma_minchunk, NULL, XDR_ENCODE, conn);

		status = clnt_compose_rpcmsg(h, procnum, &rpcmsg, call_xdrp,
		    xdr_args, argsp);

		if (status != CLNT_RDMA_SUCCESS) {
			/* Clean up from previous encode attempt */
			rdma_buf_free(conn, &rpcmsg);
			XDR_DESTROY(call_xdrp);
		} else {
			XDR_CONTROL(call_xdrp, XDR_RDMA_GET_CHUNK_LEN, &rcil);
		}
	}

	/* If the encode didn't work, then try a NOMSG */
	if (status != CLNT_RDMA_SUCCESS) {

		msglen = CKU_HDRSIZE + BYTES_PER_XDR_UNIT + MAX_AUTH_BYTES +
		    xdr_sizeof(xdr_args, argsp);

		msglen = calc_length(msglen);

		/* pick up the lengths for the reply buffer needed */
		(void) xdrrdma_sizeof(xdr_args, argsp, 0,
		    &rcil.rcil_len, &rcil.rcil_len_alt);

		/*
		 * Construct a clist to describe the CHUNK_BUFFER
		 * for the rpcmsg.
		 */
		cl_rpcmsg = clist_alloc();
		cl_rpcmsg->c_len = msglen;
		cl_rpcmsg->rb_longbuf.type = RDMA_LONG_BUFFER;
		cl_rpcmsg->rb_longbuf.len = msglen;
		if (rdma_buf_alloc(conn, &cl_rpcmsg->rb_longbuf)) {
			clist_free(cl_rpcmsg);
			goto done;
		}
		cl_rpcmsg->w.c_saddr3 = cl_rpcmsg->rb_longbuf.addr;

		op = RDMA_NOMSG;
		call_xdrp = &callxdr;

		xdrrdma_create(call_xdrp, cl_rpcmsg->rb_longbuf.addr,
		    cl_rpcmsg->rb_longbuf.len, 0,
		    cl_rpcmsg, XDR_ENCODE, conn);

		status = clnt_compose_rpcmsg(h, procnum, &rpcmsg, call_xdrp,
		    xdr_args, argsp);

		if (status != CLNT_RDMA_SUCCESS) {
			p->cku_err.re_status = RPC_CANTENCODEARGS;
			p->cku_err.re_errno = EIO;
			DTRACE_PROBE(krpc__e__clntrdma__callit__composemsg);
			goto done;
		}
	}

	/*
	 * During the XDR_ENCODE we may have "allocated" an RDMA READ or
	 * RDMA WRITE clist.
	 *
	 * First pull the RDMA READ chunk list from the XDR private
	 * area to keep it handy.
	 */
	XDR_CONTROL(call_xdrp, XDR_RDMA_GET_RLIST, &cl);

	if (gss_i_or_p) {
		long_reply_len = rcil.rcil_len + rcil.rcil_len_alt;
		long_reply_len += MAX_AUTH_BYTES;
	} else {
		long_reply_len = rcil.rcil_len;
	}

	/*
	 * Update the chunk size information for the Long RPC msg.
	 */
	if (cl && op == RDMA_NOMSG)
		cl->c_len = p->cku_outsz;

	/*
	 * Prepare the RDMA header. On success xdrs will hold the result
	 * of xdrmem_create() for a SEND_BUFFER.
	 */
	status = clnt_compose_rdma_header(conn, h, &clmsg,
	    &rdmahdr_o_xdrs, &op);

	if (status != CLNT_RDMA_SUCCESS) {
		p->cku_err.re_status = RPC_CANTSEND;
		p->cku_err.re_errno = EIO;
		RCSTAT_INCR(rcnomem);
		DTRACE_PROBE(krpc__e__clntrdma__callit__nobufs2);
		goto done;
	}

	/*
	 * Now insert the RDMA READ list iff present
	 */
	status = clnt_setup_rlist(conn, rdmahdr_o_xdrs, call_xdrp);
	if (status != CLNT_RDMA_SUCCESS) {
		DTRACE_PROBE(krpc__e__clntrdma__callit__clistreg);
		rdma_buf_free(conn, &clmsg);
		p->cku_err.re_status = RPC_CANTSEND;
		p->cku_err.re_errno = EIO;
		goto done;
	}

	/*
	 * Setup RDMA WRITE chunk list for nfs read operation
	 * other operations will have a NULL which will result
	 * as a NULL list in the XDR stream.
	 */
	status = clnt_setup_wlist(conn, rdmahdr_o_xdrs, call_xdrp, &rndup);
	if (status != CLNT_RDMA_SUCCESS) {
		rdma_buf_free(conn, &clmsg);
		p->cku_err.re_status = RPC_CANTSEND;
		p->cku_err.re_errno = EIO;
		goto done;
	}

	/*
	 * If NULL call and RPCSEC_GSS, provide a chunk such that
	 * large responses can flow back to the client.
	 * If RPCSEC_GSS with integrity or privacy is in use, get chunk.
	 */
	if ((procnum == 0 && rpcsec_gss == TRUE) ||
	    (rpcsec_gss == TRUE && gss_i_or_p == TRUE))
		long_reply_len += 1024;

	status = clnt_setup_long_reply(conn, &cl_long_reply, long_reply_len);

	if (status != CLNT_RDMA_SUCCESS) {
		rdma_buf_free(conn, &clmsg);
		p->cku_err.re_status = RPC_CANTSEND;
		p->cku_err.re_errno = EIO;
		goto done;
	}

	/*
	 * XDR encode the RDMA_REPLY write chunk
	 */
	seg_array_len = (cl_long_reply ? 1 : 0);
	(void) xdr_encode_reply_wchunk(rdmahdr_o_xdrs, cl_long_reply,
	    seg_array_len);

	/*
	 * Construct a clist in "sendlist" that represents what we
	 * will push over the wire.
	 *
	 * Start with the RDMA header and clist (if any)
	 */
	clist_add(&cl_sendlist, 0, XDR_GETPOS(rdmahdr_o_xdrs), &clmsg.handle,
	    clmsg.addr, NULL, NULL);

	/*
	 * Put the RPC call message in  sendlist if small RPC
	 */
	if (op == RDMA_MSG) {
		clist_add(&cl_sendlist, 0, p->cku_outsz, &rpcmsg.handle,
		    rpcmsg.addr, NULL, NULL);
	} else {
		/* Long RPC already in chunk list */
		RCSTAT_INCR(rclongrpcs);
	}

	/*
	 * Set up a reply buffer ready for the reply
	 */
	status = rdma_clnt_postrecv(conn, p->cku_xid);
	if (status != RDMA_SUCCESS) {
		rdma_buf_free(conn, &clmsg);
		p->cku_err.re_status = RPC_CANTSEND;
		p->cku_err.re_errno = EIO;
		goto done;
	}

	/*
	 * sync the memory for dma
	 */
	if (cl != NULL) {
		status = clist_syncmem(conn, cl, CLIST_REG_SOURCE);
		if (status != RDMA_SUCCESS) {
			(void) rdma_clnt_postrecv_remove(conn, p->cku_xid);
			rdma_buf_free(conn, &clmsg);
			p->cku_err.re_status = RPC_CANTSEND;
			p->cku_err.re_errno = EIO;
			goto done;
		}
	}

	/*
	 * Send the RDMA Header and RPC call message to the server
	 */
	status = RDMA_SEND(conn, cl_sendlist, p->cku_xid);
	if (status != RDMA_SUCCESS) {
		(void) rdma_clnt_postrecv_remove(conn, p->cku_xid);
		p->cku_err.re_status = RPC_CANTSEND;
		p->cku_err.re_errno = EIO;
		goto done;
	}

	/*
	 * RDMA plugin now owns the send msg buffers.
	 * Clear them out and don't free them.
	 */
	clmsg.addr = NULL;
	if (rpcmsg.type == SEND_BUFFER)
		rpcmsg.addr = NULL;

	/*
	 * Recv rpc reply
	 */
	status = RDMA_RECV(conn, &cl_recvlist, p->cku_xid);

	/*
	 * Now check recv status
	 */
	if (status != 0) {
		if (status == RDMA_INTR) {
			p->cku_err.re_status = RPC_INTR;
			p->cku_err.re_errno = EINTR;
			RCSTAT_INCR(rcintrs);
		} else if (status == RPC_TIMEDOUT) {
			p->cku_err.re_status = RPC_TIMEDOUT;
			p->cku_err.re_errno = ETIMEDOUT;
			RCSTAT_INCR(rctimeouts);
		} else {
			p->cku_err.re_status = RPC_CANTRECV;
			p->cku_err.re_errno = EIO;
		}
		goto done;
	}

	/*
	 * Process the reply message.
	 *
	 * First the chunk list (if any)
	 */
	rdmahdr_i_xdrs = &(p->cku_inxdr);
	xdrmem_create(rdmahdr_i_xdrs,
	    (caddr_t)(uintptr_t)cl_recvlist->w.c_saddr3,
	    cl_recvlist->c_len, XDR_DECODE);

	/*
	 * Treat xid as opaque (xid is the first entity
	 * in the rpc rdma message).
	 * Skip xid and set the xdr position accordingly.
	 */
	XDR_SETPOS(rdmahdr_i_xdrs, sizeof (uint32_t));
	(void) xdr_u_int(rdmahdr_i_xdrs, &vers);
	(void) xdr_u_int(rdmahdr_i_xdrs, &rdma_credit);
	(void) xdr_u_int(rdmahdr_i_xdrs, &op);
	(void) xdr_do_clist(rdmahdr_i_xdrs, &cl);

	clnt_update_credit(conn, rdma_credit);

	wlist_exists_reply = FALSE;
	if (! xdr_decode_wlist(rdmahdr_i_xdrs, &cl_rpcreply_wlist,
	    &wlist_exists_reply)) {
		DTRACE_PROBE(krpc__e__clntrdma__callit__wlist_decode);
		p->cku_err.re_status = RPC_CANTDECODERES;
		p->cku_err.re_errno = EIO;
		goto done;
	}

	/*
	 * The server shouldn't have sent a RDMA_SEND that
	 * the client needs to RDMA_WRITE a reply back to
	 * the server.  So silently ignoring what the
	 * server returns in the rdma_reply section of the
	 * header.
	 */
	(void) xdr_decode_reply_wchunk(rdmahdr_i_xdrs, &cl_rdma_reply);
	off = xdr_getpos(rdmahdr_i_xdrs);

	clnt_decode_long_reply(conn, cl_long_reply,
	    cl_rdma_reply, &replyxdr, &reply_xdrp,
	    cl, cl_recvlist, op, off);

	if (reply_xdrp == NULL)
		goto done;

	if (wlist_exists_reply) {
		XDR_CONTROL(reply_xdrp, XDR_RDMA_SET_WLIST, cl_rpcreply_wlist);
	}

	reply_msg.rm_direction = REPLY;
	reply_msg.rm_reply.rp_stat = MSG_ACCEPTED;
	reply_msg.acpted_rply.ar_stat = SUCCESS;
	reply_msg.acpted_rply.ar_verf = _null_auth;

	/*
	 *  xdr_results will be done in AUTH_UNWRAP.
	 */
	reply_msg.acpted_rply.ar_results.where = NULL;
	reply_msg.acpted_rply.ar_results.proc = xdr_void;

	/*
	 * Decode and validate the response.
	 */
	if (xdr_replymsg(reply_xdrp, &reply_msg)) {
		enum clnt_stat re_status;

		_seterr_reply(&reply_msg, &(p->cku_err));

		re_status = p->cku_err.re_status;
		if (re_status == RPC_SUCCESS) {
			/*
			 * Reply is good, check auth.
			 */
			if (!AUTH_VALIDATE(h->cl_auth,
			    &reply_msg.acpted_rply.ar_verf)) {
				p->cku_err.re_status = RPC_AUTHERROR;
				p->cku_err.re_why = AUTH_INVALIDRESP;
				RCSTAT_INCR(rcbadverfs);
				DTRACE_PROBE(
				    krpc__e__clntrdma__callit__authvalidate);
			} else if (!AUTH_UNWRAP(h->cl_auth, reply_xdrp,
			    xdr_results, resultsp)) {
				p->cku_err.re_status = RPC_CANTDECODERES;
				p->cku_err.re_errno = EIO;
				DTRACE_PROBE(
				    krpc__e__clntrdma__callit__authunwrap);
			}
		} else {
			/* set errno in case we can't recover */
			if (re_status != RPC_VERSMISMATCH &&
			    re_status != RPC_AUTHERROR &&
			    re_status != RPC_PROGVERSMISMATCH)
				p->cku_err.re_errno = EIO;

			if (re_status == RPC_AUTHERROR) {
				if ((refresh_attempt > 0) &&
				    AUTH_REFRESH(h->cl_auth, &reply_msg,
				    p->cku_cred)) {
					refresh_attempt--;
					try_call_again = 1;
					goto done;
				}

				try_call_again = 0;

				/*
				 * We have used the client handle to
				 * do an AUTH_REFRESH and the RPC status may
				 * be set to RPC_SUCCESS; Let's make sure to
				 * set it to RPC_AUTHERROR.
				 */
				p->cku_err.re_status = RPC_AUTHERROR;

				/*
				 * Map recoverable and unrecoverable
				 * authentication errors to appropriate
				 * errno
				 */
				switch (p->cku_err.re_why) {
				case AUTH_BADCRED:
				case AUTH_BADVERF:
				case AUTH_INVALIDRESP:
				case AUTH_TOOWEAK:
				case AUTH_FAILED:
				case RPCSEC_GSS_NOCRED:
				case RPCSEC_GSS_FAILED:
					p->cku_err.re_errno = EACCES;
					break;
				case AUTH_REJECTEDCRED:
				case AUTH_REJECTEDVERF:
				default:
					p->cku_err.re_errno = EIO;
					break;
				}
			}
			DTRACE_PROBE1(krpc__e__clntrdma__callit__rpcfailed,
			    int, p->cku_err.re_why);
		}
	} else {
Beispiel #14
0
	int
main ( int argc, char *argv[] )
{	

	if(argc !=2){
		fprintf(stderr, "usage: snowcast_server tcpport\n");
		exit(1);
	}

	/*<-SET UP PASSSIVE TCP SOCKET->*/
	struct addrinfo hints;
	
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE; 
	tcp_sourcefd = socket_setup(hints,argv[1], NULL);
	printf("tcp socket (fd %d) on port %d setup successful!\n",tcp_sourcefd, atoi(argv[1]));

	/*<-SET UP PASSIVE UDP SOCKET->*/
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC; 
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_flags = AI_PASSIVE; 
	udp_sourcefd = socket_setup(hints, argv[1], NULL);
	printf("udp socket (fd %d) on port %d setup successful!\n", udp_sourcefd, atoi(argv[1]));

	/*<-SET UP STREAMING THREADS->*/
	int i;
	for(i=0;i<STATIONNUM;i++){

	}
	struct station_info *station_0;
	spawn_stream_thread("test.text", &station_0);
	struct station_info *station_1;
	spawn_stream_thread("a.text", &station_1);
	station_0->si_next = station_1;

	/*<-MISC DECLARATION->*/
	struct station_info *s;
	struct client_info *pending_clients = NULL;

	
	/*<-INITIATE SERVICE->*/ 
	//for select()
	fd_set masterfds, readfds;
	FD_ZERO(&masterfds);
	FD_SET(0, &masterfds);
	FD_SET(tcp_sourcefd, &masterfds);
	struct timeval tv, tvcop;
	tv.tv_sec = 1;

	int maxfd = tcp_sourcefd;

	//for accepting new clients
	struct sockaddr_storage their_addr;
	socklen_t ss_size = sizeof their_addr;
	char addr_str[INET6_ADDRSTRLEN];
	if(listen(tcp_sourcefd, 10) == -1){
		perror("program: error on listen");
		exit(1);
	}

	//for talking to clients
	uint16_t numStations = 1, udpPort;
	unsigned char request[512];
	int request_bytes, response_bytes, packetSize;
	struct client_info *c;
	uint8_t commandType;

	//for talking to the user
	char command[512];
	ssize_t command_bytes;

	while(1){
		/* <-CLEAN UP FOR ANOTHER SELECT-> */
		printf("waiting...\n");
		readfds = masterfds;
		tvcop = tv;
	

		/*<-SELECT-> */
		if(select(maxfd+1, &readfds, NULL, NULL, &tvcop) == -1){
			perror("program: error on select()");
			close(tcp_sourcefd);
			//close(newfd);
			exit(1);
		}

		/*<-ACTIVE TCP SOCKET CHECK for ACTIVE CLIENTS-> */
		//expects setStation: 8 +16

		for(s=station_0;s!=NULL;s=s->si_next){
			printf("1\n");
		for(c=s->client_list;c!=NULL;c=c->ci_next){
			//did you say something, i?
			printf("checking active client %d\n",c->ci_fd);
			if(FD_ISSET(c->ci_fd, &readfds)){
				printf("new message from active client %d\n", c->ci_fd);
				if((request_bytes = recv(c->ci_fd, request, sizeof request, 0)) == -1){
					perror("recv()");
					continue;
				}

				if(!request_bytes){
					printf("client quits\n");
					//TODO get rid of the client from the active list
					//TODO how to get the next highest fd number?
					if(c->ci_fd == maxfd) maxfd = maxfd-1;
					FD_CLR(c->ci_fd, &masterfds);
					close(c->ci_fd);
					continue; 
				}

				unpack(request, "ch", &commandType, &udpPort);
				printf("bytes_received: %d \n commandType: %hd\n udpPort: %d\n", request_bytes, commandType, udpPort);
			}

		}
		}
	
		/*<-PASSIVE TCP: New Client connect()-> */	
		if (FD_ISSET(tcp_sourcefd, &readfds)){
			client_count++;
			printf("new client!\n");

			int clientfd = accept(tcp_sourcefd, (struct sockaddr *)&their_addr, &ss_size);
			if ( clientfd == -1 ) {
				perror("program: error on accept()\n");
				close(tcp_sourcefd);
				exit(1);
			}

			//announce new connection
			inet_ntop(their_addr.ss_family,
				get_in_addr( (struct sockaddr *)&their_addr),
				addr_str, sizeof addr_str);
			printf("connection accepted from: %s\n", addr_str);

			//make client_info struct 
			struct client_info *newclient = (struct client_info *) malloc(sizeof(struct client_info));
			newclient->ci_family = their_addr.ss_family;
			newclient->ci_addr = addr_str;
			newclient->ci_next = NULL;
			newclient->ci_fd = clientfd;

			//add client to the pending list
			printf("new connection fd: %d\n",clientfd);
			clist_add(newclient, &pending_clients);
			clist_display(&pending_clients);
			FD_SET(clientfd, &masterfds);
			if(maxfd<clientfd)maxfd= clientfd;
		}

	

		/*<-ACTIVE TCP SOCKET CHECK for PENDING CLIENTS-> */
		//expects hello: 8 + 16
		for(c=pending_clients;c!= NULL;c=c->ci_next){
			printf("checking pending client %d\n", c->ci_fd);
			if(FD_ISSET(c->ci_fd, &readfds)){
				printf("new message from pending client %d\n", c->ci_fd);
				if((request_bytes = recv(c->ci_fd, request, sizeof request, 0)) == -1){
					perror("recv()");
					continue;
				}
				if(!request_bytes){
					printf("client quits\n");
					//TODO get rid of the client from the pending list
					//-----unfortunately, this client has not been able to provide us with his
					//-----UDP port. He passed away too early.
					//TODO how to get the next highest fd number?
					if(c->ci_fd == maxfd) maxfd = maxfd-1;
					FD_CLR(c->ci_fd, &masterfds);
					close(c->ci_fd);
					continue; 
				}	

				unpack(request, "ch", &commandType, &udpPort);
				printf("bytes_received: %d \n commandType: %hd\n udpPort: %d\n", request_bytes, commandType, udpPort);
 
				//was that a hello?
				if(commandType == 0){
					printf("hello received\n");

					//send back welcome
					int welcomesize = sizeof(uint8_t) + sizeof(uint16_t);
					unsigned char response[welcomesize];
					packetSize = pack(response, "ch", (uint8_t)0, (uint16_t)numStations);

					if( (response_bytes = send(c->ci_fd, response, sizeof response, 0)) == -1){
						perror("send() failed");
						exit(1);
					}
					if(packetSize != response_bytes){
						printf("%d bytes have been packed, but %d bytes have been sent\n", packetSize, response_bytes);
						exit(1);
					}

					//complete client's struct info
					c->ci_udp = udpPort;
					struct sockaddr_in *addr = malloc(sizeof(struct sockaddr_in));
					addr->sin_family = c->ci_family;
					addr->sin_port = htons(c->ci_udp);
					addr->sin_addr = *((struct in_addr *) gethostbyname(c->ci_addr)->h_addr);
					c->ci_udp_addr = (struct sockaddr *) addr;

					//add client to default stations client list
					printf("i->ci_fd: %d\n", c->ci_fd);
					if(client_count==1)clist_add(c,&station_0->client_list);
					if(client_count==2)clist_add(c,&station_1->client_list);
					clist_remove(c,&pending_clients);
					printf("pending list: ");
					clist_display(&pending_clients);
					printf("active list: ");
					clist_display(&station_0->client_list);
				} else {
					//invalid command
					clist_remove(c, &pending_clients);
					FD_CLR(c->ci_fd, &masterfds);
				}
			}
		}


		/*<-STDIN CHECK-> */	
		if(FD_ISSET(0, &readfds)){
			printf("new command!\n");
			command_bytes = read(0, command, sizeof command);
			if(command_bytes == -1){
				perror("read()");
				exit(1);
			}
			command[command_bytes] = '\0';
			printf("server admin command: %s\n", command);	
		}
	}
	
	return EXIT_SUCCESS;
}				/* ----------  end of function main  ---------- */ 
Beispiel #15
0
void
add (hand *h, card c) {
    clist_add(&h->cards, c);
}
Beispiel #16
0
/*
 * add_radar_q
 *
 * It returns the radar_q struct which handles the pkt.from node.
 * If the node is not present in the radar_q, it is added, and the
 * relative struct will be returned.
 */
struct
    radar_queue *
add_radar_q(PACKET pkt)
{
    map_node *rnode;
    quadro_group quadg;
    struct radar_queue *rq;
    u_int ret = 0;
    int dev_pos;

    if (me.cur_node->flags & MAP_HNODE) {
        /*
         * We are hooking, we haven't yet an int_map, an ext_map,
         * a stable ip, so we create fake nodes that will be delete after
         * the hook.
         */
        if (!(rq = find_ip_radar_q(&pkt.from))) {
            map_rnode rnn;

            rnode = xmalloc(sizeof(map_node));
            setzero(rnode, sizeof(map_node));
            setzero(&rnn, sizeof(map_rnode));

            rnn.r_node = (int *) me.cur_node;
            rnode_add(rnode, &rnn);
        } else
            rnode = rq->node;
    }

    iptoquadg(pkt.from, me.ext_map, &quadg,
              QUADG_GID | QUADG_GNODE | QUADG_IPSTART);

    if (!(me.cur_node->flags & MAP_HNODE)) {
        iptomap((u_int) me.int_map, pkt.from, me.cur_quadg.ipstart[1],
                &rnode);
        ret = quadg_gids_cmp(me.cur_quadg, quadg, 1);
    }

    if (!ret)
        rq = find_node_radar_q(rnode);
    else
        rq = find_ip_radar_q(&pkt.from);

    if (!rq) {
        /*
         * If pkt.from isn't already in the queue, add it.
         */

        rq = xzalloc(sizeof(struct radar_queue));

        if (ret)
            rq->node = (map_node *) RADQ_EXT_RNODE;
        else {
            rq->node = rnode;
            /* This pkt has been sent from another hooking
             * node, let's remember this. */
            if (pkt.hdr.flags & HOOK_PKT)
                rq->node->flags |= MAP_HNODE;
        }

        if (pkt.hdr.flags & HOOK_PKT)
            rq->flags |= MAP_HNODE;

        inet_copy(&rq->ip, &pkt.from);
        memcpy(&rq->quadg, &quadg, sizeof(quadro_group));
        rq->dev[0] = pkt.dev;
        rq->dev_n++;

        clist_add(&radar_q, &radar_q_counter, rq);
    } else {
        /*
         * Check if the input device is in the rq->dev array,
         * if not add it.
         */
        if (rq->dev_n < MAX_INTERFACES) {
            dev_pos = FIND_PTR(pkt.dev, rq->dev, rq->dev_n);
            if (dev_pos < 0)
                rq->dev[rq->dev_n++] = pkt.dev;
        }
    }

    return rq;
}