Пример #1
0
static void
error_print(void)
{
#if 0
    VALUE errat = Qnil;		/* OK */
    VALUE errinfo = GET_THREAD()->errinfo;
    volatile VALUE eclass, e;
    const char *einfo;
    long elen;

    if (NIL_P(errinfo))
	return;

    PUSH_TAG();
    if (EXEC_TAG() == 0) {
	errat = get_backtrace(errinfo);
    }
    else {
	errat = Qnil;
    }
    if (EXEC_TAG())
	goto error;
    if (NIL_P(errat)) {
	const char *file = rb_sourcefile();
	int line = rb_sourceline();
	if (file)
	    warn_printf("%s:%d", file, line);
	else
	    warn_printf("%d", line);
    }
    else if (RARRAY_LEN(errat) == 0) {
	error_pos();
    }
    else {
	VALUE mesg = RARRAY_AT(errat, 0);

	if (NIL_P(mesg))
	    error_pos();
	else {
	    warn_print2(RSTRING_PTR(mesg), RSTRING_LEN(mesg));
	}
    }

    eclass = CLASS_OF(errinfo);
    if (EXEC_TAG() == 0) {
	e = rb_funcall(errinfo, rb_intern("message"), 0, 0);
	StringValue(e);
	einfo = RSTRING_PTR(e);
	elen = RSTRING_LEN(e);
    }
    else {
	einfo = "";
	elen = 0;
    }
    if (EXEC_TAG())
	goto error;
    if (eclass == rb_eRuntimeError && elen == 0) {
	warn_print(": unhandled exception\n");
    }
    else {
	VALUE epath;

	epath = rb_class_name(eclass);
	if (elen == 0) {
	    warn_print(": ");
	    warn_print2(RSTRING_PTR(epath), RSTRING_LEN(epath));
	    warn_print("\n");
	}
	else {
	    char *tail = 0;
	    long len = elen;

	    if (RSTRING_PTR(epath)[0] == '#')
		epath = 0;
	    if ((tail = memchr(einfo, '\n', elen)) != 0) {
		len = tail - einfo;
		tail++;		/* skip newline */
	    }
	    warn_print(": ");
	    warn_print2(einfo, len);
	    if (epath) {
		warn_print(" (");
		warn_print2(RSTRING_PTR(epath), RSTRING_LEN(epath));
		warn_print(")\n");
	    }
	    if (tail) {
		warn_print2(tail, elen - len - 1);
		if (einfo[elen-1] != '\n') warn_print2("\n", 1);
	    }
	}
    }

    if (!NIL_P(errat)) {
	long i;
	long len = RARRAY_LEN(errat);
        int skip = eclass == rb_eSysStackError;
	
#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
#define TRACE_HEAD 8
#define TRACE_TAIL 5

	for (i = 1; i < len; i++) {
	    VALUE v = RARRAY_AT(errat, i);
	    if (TYPE(v) == T_STRING) {
		warn_printf("\tfrom %s\n", RSTRING_PTR(v));
	    }
	    if (skip && i == TRACE_HEAD && len > TRACE_MAX) {
		warn_printf("\t ... %ld levels...\n",
			    len - TRACE_HEAD - TRACE_TAIL);
		i = len - TRACE_TAIL;
	    }
	}
    }
  error:
    POP_TAG();
#endif
}
Пример #2
0
int msg_start (Domain_t *dp)
{
	Reader_t	*rp;
	TopicType_t	*tp;
	int		error;

	error = DDS_DomainParticipant_register_type ((DDS_DomainParticipant) dp,
						     dds_participant_msg_ts,
						     "ParticipantMessageData");
	if (error) {
		warn_printf ("disc_start: can't register ParticipantMessageData type!");
		return (error);
	}
	if (lock_take (dp->lock)) {
		warn_printf ("disc_start: domain lock error (2)");
		return (DDS_RETCODE_ERROR);
	}
	tp = type_lookup (dp, "ParticipantMessageData");
	if (tp)
		tp->flags |= EF_BUILTIN;
	lock_release (dp->lock);

	/* Create builtin Participant Message Reader. */
	error = create_builtin_endpoint (dp, EPB_PARTICIPANT_MSG_R,
					 0, 1,
					 1, 0, 1,
					 NULL,
					 dp->participant.p_meta_ucast,
					 dp->participant.p_meta_mcast,
					 NULL);
	if (error)
		return (error);

	/* Attach to builtin Participant Message Reader. */
	rp = (Reader_t *) dp->participant.p_builtin_ep [EPB_PARTICIPANT_MSG_R];
	error = hc_request_notification (rp->r_cache, disc_data_available, (uintptr_t) rp);
	if (error) {
		fatal_printf ("msg_start: can't register Message Reader!");
		return (error);
	}

	/* Create builtin Participant Message Writer. */
	error = create_builtin_endpoint (dp, EPB_PARTICIPANT_MSG_W,
					 1, 1,
					 1, 0, 1,
					 NULL,
					 dp->participant.p_meta_ucast,
					 dp->participant.p_meta_mcast,
					 NULL);
	if (error)
		return (error);

#if defined (DDS_SECURITY) && defined (DDS_NATIVE_SECURITY)

	if (NATIVE_SECURITY (dp)) {

		/* Create builtin Participant Secure Message Reader. */
		error = create_builtin_endpoint (dp, EPB_PARTICIPANT_MSG_SEC_R,
						 0, 1,
						 1, 0, 1,
						 NULL,
						 dp->participant.p_meta_ucast,
						 dp->participant.p_meta_mcast,
						 NULL);
		if (error)
			return (error);

		/* Attach to builtin Participant Secure Message Reader. */
		rp = (Reader_t *) dp->participant.p_builtin_ep [EPB_PARTICIPANT_MSG_SEC_R];
		error = hc_request_notification (rp->r_cache, disc_data_available, (uintptr_t) rp);
		if (error) {
			fatal_printf ("msg_start: can't register secure Message Reader!");
			return (error);
		}

		/* Create builtin Participant Secure Message Writer. */
		error = create_builtin_endpoint (dp, EPB_PARTICIPANT_MSG_SEC_W,
						 1, 1,
						 1, 0, 1,
						 NULL,
						 dp->participant.p_meta_ucast,
						 dp->participant.p_meta_mcast,
						 NULL);
		if (error)
			return (error);
	}
#endif
	return (DDS_RETCODE_OK);
}
Пример #3
0
static void tcp_server_accept (SOCKET fd, short revents, void *arg)
{
	IP_CX			*scxp = (IP_CX *) arg;
	TCP_FD			*pp;
	struct sockaddr_in	peer_addr;
#ifdef DDS_IPV6
	struct sockaddr_in6	peer_addr_v6;
#endif
	struct sockaddr		*caddr;
	socklen_t		size;
	uint32_t		a4;
	int			r;

	trace_poll_events (fd, revents, arg);

	memset (&scxp->dst_addr, 0, sizeof (scxp->dst_addr));
	if (scxp->locator->locator.kind == LOCATOR_KIND_TCPv4) {
		peer_addr.sin_family = AF_INET;
		caddr = (struct sockaddr *) &peer_addr;
		size = sizeof (struct sockaddr_in);
	}
#ifdef DDS_IPV6
	else if (scxp->locator->locator.kind == LOCATOR_KIND_TCPv6) {
		peer_addr_v6.sin6_family = AF_INET6;
		caddr = (struct sockaddr *) &peer_addr_v6;
		size = sizeof (struct sockaddr_in6);
	}
#endif
	else {
		warn_printf ("TCP(S): unknown address family!");
		return;
	}
#ifdef TCP_ACCEPT_DELAY_MS
	usleep (TCP_ACCEPT_DELAY_MS * 1000);
#endif
	r = accept (fd, caddr, &size);

	ctrc_begind (TCPS_ID, TCPS_SERVER_EV, &fd, sizeof (fd));
	ctrc_contd (&revents, sizeof (revents));
	ctrc_contd (caddr, size);
	ctrc_contd (&r, sizeof (r));
	ctrc_endd ();

	trace_server ("accept", r, fd);
	if (r < 0) {
		perror ("tcp_server_accept: accept()");
		log_printf (RTPS_ID, 0, "tcp_server_accept: accept() failed - errno = %d.\r\n", ERRNO);
		return;
	}

#ifdef DDS_TCP_NODELAY
	sock_set_tcp_nodelay (r);
#endif

	/* Create a new pending TCP connection. */
	pp = xmalloc (sizeof (TCP_FD));
	if (!pp) {
		ctrc_printd (TCPS_ID, TCPS_FD_NOMEM, &r, sizeof (r));
		close (r); /* bad reuse of variable in error case */
		trace_server ("close", 0, r);
		log_printf (RTPS_ID, 0, "TCP(S): allocation failure!\r\n");
		return;
	}
	memset (pp, 0, sizeof (TCP_FD));
	pp->fd = r;
	if (scxp->locator->locator.kind == LOCATOR_KIND_TCPv4) {
		a4 = ntohl (peer_addr.sin_addr.s_addr);
		memset (pp->dst_addr, 0, 12);
		pp->dst_addr [12] = a4 >> 24;
		pp->dst_addr [13] = (a4 >> 16) & 0xff;
		pp->dst_addr [14] = (a4 >> 8) & 0xff;
		pp->dst_addr [15] = a4 & 0xff;
		pp->dst_port = ntohs (peer_addr.sin_port);
	}
Пример #4
0
static int
error_handle(int ex)
{
    int status = EXIT_FAILURE;
    rb_thread_t *th = GET_THREAD();

    if (rb_thread_set_raised(th))
	return EXIT_FAILURE;
    switch (ex & TAG_MASK) {
      case 0:
	status = EXIT_SUCCESS;
	break;

      case TAG_RETURN:
	error_pos();
	warn_print(": unexpected return\n");
	break;
      case TAG_NEXT:
	error_pos();
	warn_print(": unexpected next\n");
	break;
      case TAG_BREAK:
	error_pos();
	warn_print(": unexpected break\n");
	break;
      case TAG_REDO:
	error_pos();
	warn_print(": unexpected redo\n");
	break;
      case TAG_RETRY:
	error_pos();
	warn_print(": retry outside of rescue clause\n");
	break;
      case TAG_THROW:
	/* TODO: fix me */
	error_pos();
	warn_printf(": unexpected throw\n");
	break;
      case TAG_RAISE: {
	VALUE errinfo = GET_THREAD()->errinfo;
	if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
	    status = sysexit_status(errinfo);
	}
	else if (rb_obj_is_instance_of(errinfo, rb_eSignal)) {
	    /* no message when exiting by signal */
	}
	else {
	    error_print();
	}
	break;
      }
      case TAG_FATAL:
	error_print();
	break;
      default:
	rb_bug("Unknown longjmp status %d", ex);
	break;
    }
    rb_thread_reset_raised(th);
    return status;
}
Пример #5
0
/* Write/send (the next part of) a msg (fragment). */
static void tcp_write_message_fragment (IP_CX *cxp)
{
	ssize_t		n, max;
	unsigned char	*sp;
	TCP_DATA	*dp;

	ctrc_printd (TCPS_ID, TCPS_TX_FRAG, &cxp->fd, sizeof (cxp->fd));
	if ((dp = cxp->sproto) == NULL) {
		warn_printf ("tcp_write_message_fragment: no TCP context!");
		return;
	}
	if (!dp->send_msg) {
		warn_printf ("tcp_write_message_fragment: no send_msg context!");
#ifdef TRACE_POLL_EVENTS
			log_printf (RTPS_ID, 0, "TLS: POLLOUT = 0 [%d]\r\n", cxp->fd);
#endif
			sock_fd_event_socket (cxp->fd, POLLOUT, 0);
		return;
	}
	sp = dp->send_msg->buffer + dp->send_msg->used;
	while (dp->send_msg->used < dp->send_msg->size) {
		max = dp->send_msg->size - dp->send_msg->used;

#ifdef __APPLE__
		/* Apple does not support MSG_NOSIGNAL, therefore we set the equivalent Apple-specific 
		   socket option SO_NOSIGPIPE. */
		n = send (cxp->fd, sp, max, 0);
#else
		/* We're using send() here iso write() so that we can indicate to the kernel *not* to send
		   a SIGPIPE in case the other already closed this connection. A return code of -1 and ERRNO
		   to EPIPE is given instead */
		n = send (cxp->fd, sp, max, MSG_NOSIGNAL);
#endif
		ctrc_begind (TCPS_ID, TCPS_TX_CHUNK, &cxp->fd, sizeof (cxp->fd));
		ctrc_contd (&max, sizeof (max));
		ctrc_contd (&n, sizeof (n));
		ctrc_endd ();

		trace_write (n, cxp->fd, max);
		if (n < 0) {
			if (ERRNO == EINTR)
				continue; /* immediately try again */

			if ((ERRNO == EAGAIN) || (ERRNO == EWOULDBLOCK))
				return; /* Wait for poll() to indicate that we can write another chunk. */

			/*perror ("tcp_write_message_fragment");*/
			log_printf (RTPS_ID, 0, "%s: error sending data on [%d] (%s).\r\n",
					__FUNCTION__, cxp->fd, strerror (ERRNO));
			xfree (dp->send_msg->buffer);
			xfree (dp->send_msg);
			dp->send_msg = NULL;
			tcp_cleanup_ctx (cxp);
			return;
		}
		dp->send_msg->used += n;
		sp += n;
	}
	xfree (dp->send_msg->buffer);
	xfree (dp->send_msg);
	dp->send_msg = NULL;
#ifdef TRACE_POLL_EVENTS
	log_printf (RTPS_ID, 0, "TLS: POLLOUT = 0 [%d]\r\n", cxp->fd);
#endif
	sock_fd_event_socket (cxp->fd, POLLOUT, 0);

	ctrc_printd (TCPS_ID, TCPS_TX_COMPL, &cxp->fd, sizeof (cxp->fd));

	if (cxp->stream_cb->on_write_completed)
		cxp->stream_cb->on_write_completed (cxp);
	else if (cxp->paired &&
		 cxp->paired->fd == cxp->fd &&
		 cxp->paired->stream_cb->on_write_completed)
		cxp->paired->stream_cb->on_write_completed (cxp);
}
Пример #6
0
static int tcp_do_connect (TCP_CON_REQ_ST *p)
{
	TCP_CON_LIST_ST		*hp;
	TCP_DATA		*dp;
	struct sockaddr_in	sa_v4;
#ifdef DDS_IPV6
	struct sockaddr_in6	sa_v6;
#endif
	struct sockaddr		*sa;
	socklen_t		len;
	unsigned		family;
	short			events;
	int			fd, r, err;
#ifdef __APPLE__
	int			yes = 1;
#endif

	trc_con1 ("tcp_do_connect(cp=%p);\r\n", (void *) p);
	do {
		/* No connect() in progress currently! */
		hp = p->head;
		if ((hp->locator.kind & LOCATOR_KINDS_IPv4) != 0) {
			sa_v4.sin_family = family = AF_INET;
			sa_v4.sin_port = htons (hp->locator.port);
			sa = (struct sockaddr *) &sa_v4;
			len = sizeof (sa_v4);
			sa_v4.sin_addr.s_addr = htonl ((hp->locator.address [12] << 24) |
						       (hp->locator.address [13] << 16) |
						       (hp->locator.address [14] << 8) |
						        hp->locator.address [15]);
			ctrc_printd (TCPS_ID, TCPS_DO_CON, hp->locator.address + 12, 4);
		}
#ifdef DDS_IPV6
		else if ((hp->locator.kind & LOCATOR_KINDS_IPv6) != 0) {
			sa_v6.sin6_family = family = AF_INET6;
			memcpy (sa_v6.sin6_addr.s6_addr, hp->locator.address, 16);
			sa_v6.sin6_port = htons (hp->locator.port);
			sa = (struct sockaddr *) &sa_v6;
			len = sizeof (sa_v6);
			ctrc_printd (TCPS_ID, TCPS_DO_CON, hp->locator.address, 16);
		}
#endif
		else {
			log_printf (RTPS_ID, 0, "tcp_do_connect: invalid locator kind!\r\n");
			return (-2);
		}
		dp = xmalloc (sizeof (TCP_DATA));
		if (!dp) {
			warn_printf ("tcp_connect: out of memory for TCP context!");
			return (-2);
		}
		dp->send_msg = dp->recv_msg = NULL;

		fd = socket (family, SOCK_STREAM, IPPROTO_TCP);
		trace_client ("socket", fd, -1);
		if (fd < 0) {
			xfree (dp);
			/*perror ("tcp_do_connect: socket()");*/
			log_printf (RTPS_ID, 0, "tcp_do_connect: socket() failed - errno = %d.\r\n", ERRNO);
			return (-2);
		}
		p->cxp->fd = fd;
		p->cxp->fd_owner = 1;
		p->cxp->sproto = dp;

#ifdef __APPLE__
		/* MSG_NOSIGNAL does not exist for Apple OS, but a equivalent socket option is available */
		if (setsockopt (fd, SOL_SOCKET, SO_NOSIGPIPE, &yes, sizeof (yes)) < 0)
			perror ("tcp_do_connect: setsockopt()");
#endif
#ifdef DDS_TCP_NODELAY
		sock_set_tcp_nodelay (fd);
#endif
		sock_set_socket_nonblocking (fd);
		events = POLLIN | POLLPRI | POLLHUP | POLLNVAL;
		for (;;) {
			r = connect (fd, sa, len);

			ctrc_begind (TCPS_ID, TCPS_SYS_CON, &fd, sizeof (fd));
			ctrc_contd (&r, sizeof (r));
			ctrc_endd ();

			trace_client ("connect", r, fd);
			if (r == -1) {
				err = ERRNO;
				if (err == EINTR)
					continue;

				if (err != EINPROGRESS) {
					ctrc_printd (TCPS_ID, TCPS_CON_ERR, &fd, sizeof (fd));
					/*perror ("tcp_do_connect: connect()");*/
					log_printf (RTPS_ID, 0, "tcp_do_connect: connect() failed - errno = %d.\r\n", err);
					close (fd);
					trace_server ("close", r, fd);
					p->cxp->cx_state = CXS_WRETRY;
					p->cxp->fd = 0;
					p->cxp->fd_owner = 0;
				}
				else {
					log_printf (RTPS_ID, 0, "TCP: connecting to server [%d] ...\r\n", fd);
					p->cxp->cx_state = CXS_CONNECT;
					sock_fd_add_socket (fd, events | POLLOUT, tcp_wait_connect_complete, p, "DDS.TCP-C");
					ctrc_printd (TCPS_ID, TCPS_CON_WAIT, &fd, sizeof (fd));
					return (-1);
				}
			}
			else {
				log_printf (RTPS_ID, 0, "TCP: connected to server [%d]\r\n", fd);
				p->cxp->cx_state = CXS_OPEN;
				ctrc_printd (TCPS_ID, TCPS_CON_OK, &fd, sizeof (fd));
				sock_fd_add_socket (fd, events, tcp_socket_activity, p->cxp, "DDS.TCP-C");
			}
			break;
		}
		p = tcp_clear_pending_connect (p);
	}
	while (p);
	return (r);
}
Пример #7
0
static void
error_print(void)
{
    volatile VALUE errat = Qundef;
    rb_thread_t *th = GET_THREAD();
    VALUE errinfo = th->errinfo;
    int raised_flag = th->raised_flag;
    volatile VALUE eclass = Qundef, e = Qundef;
    const char *volatile einfo;
    volatile long elen;

    if (NIL_P(errinfo))
	return;
    rb_thread_raised_clear(th);

    TH_PUSH_TAG(th);
    if (TH_EXEC_TAG() == 0) {
	errat = get_backtrace(errinfo);
    }
    else if (errat == Qundef) {
	errat = Qnil;
    }
    else if (eclass == Qundef || e != Qundef) {
	goto error;
    }
    else {
	goto no_message;
    }
    if (NIL_P(errat)) {
	const char *file = rb_sourcefile();
	int line = rb_sourceline();
	if (!file)
	    warn_printf("%d", line);
	else if (!line)
	    warn_printf("%s", file);
	else
	    warn_printf("%s:%d", file, line);
    }
    else if (RARRAY_LEN(errat) == 0) {
	error_pos();
    }
    else {
	VALUE mesg = RARRAY_AREF(errat, 0);

	if (NIL_P(mesg))
	    error_pos();
	else {
	    warn_print_str(mesg);
	}
    }

    eclass = CLASS_OF(errinfo);
    if (eclass != Qundef &&
	(e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0)) != Qundef &&
	(RB_TYPE_P(e, T_STRING) || !NIL_P(e = rb_check_string_type(e)))) {
	einfo = RSTRING_PTR(e);
	elen = RSTRING_LEN(e);
    }
    else {
      no_message:
	einfo = "";
	elen = 0;
    }
    if (eclass == rb_eRuntimeError && elen == 0) {
	warn_print(": unhandled exception\n");
    }
    else {
	VALUE epath;

	epath = rb_class_name(eclass);
	if (elen == 0) {
	    warn_print(": ");
	    warn_print_str(epath);
	    warn_print("\n");
	}
	else {
	    char *tail = 0;
	    long len = elen;

	    if (RSTRING_PTR(epath)[0] == '#')
		epath = 0;
	    if ((tail = memchr(einfo, '\n', elen)) != 0) {
		len = tail - einfo;
		tail++;		/* skip newline */
	    }
	    warn_print(": ");
	    warn_print_str(tail ? rb_str_subseq(e, 0, len) : e);
	    if (epath) {
		warn_print(" (");
		warn_print_str(epath);
		warn_print(")\n");
	    }
	    if (tail) {
		warn_print_str(rb_str_subseq(e, tail - einfo, elen - len - 1));
	    }
	    if (tail ? einfo[elen-1] != '\n' : !epath) warn_print2("\n", 1);
	}
    }

    if (!NIL_P(errat)) {
	long i;
	long len = RARRAY_LEN(errat);
        int skip = eclass == rb_eSysStackError;

#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
#define TRACE_HEAD 8
#define TRACE_TAIL 5

	for (i = 1; i < len; i++) {
	    VALUE line = RARRAY_AREF(errat, i);
	    if (RB_TYPE_P(line, T_STRING)) {
		warn_printf("\tfrom %"PRIsVALUE"\n", line);
	    }
	    if (skip && i == TRACE_HEAD && len > TRACE_MAX) {
		warn_printf("\t ... %ld levels...\n",
			    len - TRACE_HEAD - TRACE_TAIL);
		i = len - TRACE_TAIL;
	    }
	}
    }
  error:
    TH_POP_TAG();
    th->errinfo = errinfo;
    rb_thread_raised_set(th, raised_flag);
}
Пример #8
0
static void sfr_rel_data (RemWriter_t         *rwp,
			  Change_t            *cp,
			  SequenceNumber_t    *cpsnr,
			  const KeyHash_t     *hp,
			  const unsigned char *key,
			  size_t              keylen,
#ifdef RTPS_FRAGMENTS
			  DataFragSMsg        *fragp,
			  FragInfo_t	      **finfo,
#endif
			  int                 ignore)
{
	ENDPOINT	*ep = &rwp->rw_reader->endpoint;
	CCREF		*rp, *gap_rp;
	HCI		hci;
	Change_t	*ncp;
	InstanceHandle	h;
	SequenceNumber_t gap_first, gap_last, seqnr_first, seqnr_last;
	RejectCause_t	cause;
	/*unsigned	max;*/
	int		error, ooo;

	ctrc_printd (RTPS_ID, RTPS_SFR_REL_DATA, &rwp, sizeof (rwp));
	prof_start (rtps_rr_data);
#if defined (RTPS_FRAGMENTS) && defined (EXTRA_STATS)
	if (fragp)
		STATS_INC (rwp->rw_ndatafrags);
	else
#endif
		STATS_INC (rwp->rw_ndata);

	RW_SIGNAL (rwp, "REL-Data");

#ifdef RTPS_MARKERS
	if (rwp->rw_reader->endpoint.mark_data)
		rtps_marker_notify (rwp->rw_reader->endpoint.endpoint, EM_DATA, "sfr_rel_data");
#endif
#ifdef RTPS_INIT_ACKNACK

	/* If first Data: accept it and become alive. */
	if (!rwp->rw_peer_alive)
		sfr_rel_alive (rwp);
#endif
	rwp->rw_hb_no_data = 0;

	/* If seqnr already in cache: ignore sample. */
	if (SEQNR_LT (*cpsnr, rwp->rw_seqnr_next)) {
		RW_SIGNAL (rwp, "REL-Data: ignore (SNR < hcache.SNR)");
		return;
	}
	ooo = !SEQNR_EQ (rwp->rw_seqnr_next, *cpsnr);

	/* Create a new instance already, if possible. */
	if (ignore
#ifdef RTPS_FRAGMENTS
	           || fragp
#endif
		           )
		hci = NULL;
	else if (ep->multi_inst) {
		hci = hc_lookup_hash (ep->endpoint->cache, hp, key, keylen,
					  &h, 1, ooo, &cause);
		if (!hci) {
			/* Don't see this as rejected -- since there is no ack
			   given, sample will be retransmitted!
			dcps_sample_rejected ((Reader_t *) ep->endpoint,
					      (DDS_SampleRejectedStatusKind) cause,
					      h);*/
			if (!ooo)
				rwp->rw_blocked = 1;
			return;
		}
	}
	else {
		if (!hc_accepts (ep->endpoint->cache, ooo)) {
			/* Don't see this as rejected -- since there is no ack
			   given, sample will be retransmitted!
			dcps_sample_rejected ((Reader_t *) ep->endpoint,
					      DDS_REJECTED_BY_SAMPLES_LIMIT, 0);*/
			if (!ooo)
				rwp->rw_blocked = 1;
			return;
		}
		h = 0;
		hci = NULL;
	}

	/* Add to changes list of proxy writer context. */
	if (LIST_NONEMPTY (rwp->rw_changes)) { /* Already some samples queued. */

		RW_SIGNAL (rwp, "REL-Data: changes-queued");

		if (hci)
			hc_inst_inform (ep->endpoint->cache, hci);

		if (rwp->rw_changes.head->relevant)
			seqnr_first = rwp->rw_changes.head->u.c.change->c_seqnr;
		else
			seqnr_first = rwp->rw_changes.head->u.range.first;
		if (rwp->rw_changes.tail->relevant)
			seqnr_last = rwp->rw_changes.tail->u.c.change->c_seqnr;
		else
			seqnr_last = rwp->rw_changes.tail->u.range.last;

		if (SEQNR_GT (*cpsnr, seqnr_last)) { /* Seqnr > last in list! */

			/* Add new data sample node after tail of list. */
			RW_SIGNAL (rwp, "REL-Data: add-missing>last");
			gap_first = seqnr_last;
			SEQNR_INC (gap_first);
			if (!SEQNR_EQ (gap_first, *cpsnr)) {

				/* Gap between tail and data: add MISSING sample
				   node between current tail of list and to be
				   added data sample node. */
				gap_last = *cpsnr;
				SEQNR_DEC (gap_last);
				if (!rwp->rw_changes.tail->relevant &&
				    rwp->rw_changes.tail->state == CS_MISSING) {

					/* Extend previous gap node. */
					rwp->rw_changes.tail->u.range.last = gap_last;
					RW_SIGNAL (rwp, "REL-Data: extend-gap");
				}
				else {	/* Add new gap node. */
					gap_rp = ccref_add_gap (&rwp->rw_changes,
							        &gap_first,
							        &gap_last,
							        1,
								CS_MISSING);
					if (!gap_rp)
						return;

					RW_SIGNAL (rwp, "REL-Data: add-gap");
				}
			}

			/* Append data sample node. */
			if (ignore)
				rp = ccref_add_gap (&rwp->rw_changes, cpsnr,
						    cpsnr, 1, CS_RECEIVED);
			else
				rp = ccref_add_received (&rwp->rw_changes, cp,
							 cpsnr, hci, h, 1);
			if (!rp)
				return;

			rwp->rw_reader->data_queued++;
#ifdef RTPS_FRAGMENTS
			if (fragp) {
				sfr_fragment (rwp, rp, fragp, finfo, hp, cp, ooo, ignore);
				return;
			}
#endif
			RANGE_CHECK (&rwp->rw_changes, "REL-Data: >last");
		}
		else if (SEQNR_LT (*cpsnr, seqnr_first)) { /* Seqnr < first! */

			/* Add new data sample node before head of list. */
			RW_SIGNAL (rwp, "REL-Data: add-missing<first");
			gap_last = seqnr_first;
			SEQNR_DEC (gap_last);
			if (!SEQNR_EQ (gap_last, *cpsnr)) {

				/* Gap between data and head: add MISSING sample
				   node between to be added data sample and
				   current head of list. */
				gap_first = *cpsnr;
				SEQNR_INC (gap_first);
				if (!rwp->rw_changes.head->relevant &&
				    rwp->rw_changes.tail->state == CS_MISSING) {

					/* Extended following gap node. */
					rwp->rw_changes.head->u.range.first = gap_first;
					RW_SIGNAL (rwp, "REL-Data: extend-gap");
				}
				else {	/* Add new gap node. */
					gap_rp = ccref_add_gap (&rwp->rw_changes,
							        &gap_first,
							        &gap_last,
							        0,
								CS_MISSING);
					if (!gap_rp)
						return;

					RW_SIGNAL (rwp, "REL-Data: add-gap");
				}
			}

			/* Prepend data sample node. */
			if (ignore)
				rp = ccref_add_gap (&rwp->rw_changes, cpsnr,
							 cpsnr, 0, CS_RECEIVED);
			else
				rp = ccref_add_received (&rwp->rw_changes, cp,
							 cpsnr, hci, h, 0);
			if (!rp)
				return;

			rwp->rw_reader->data_queued++;
#ifdef RTPS_FRAGMENTS
			if (fragp) {
				sfr_fragment (rwp, rp, fragp, finfo, hp, cp, ooo, ignore);
				return;
			}
#endif
			RANGE_CHECK (&rwp->rw_changes, "REL-Data: <first");
		}
		else {	/* Seqnr somewhere in list - lets find it. */
			LIST_FOREACH (rwp->rw_changes, rp)
				if (rp->relevant) {
					if (SEQNR_EQ (rp->u.c.change->c_seqnr, *cpsnr))
						break;
				}
				else if (!SEQNR_LT (*cpsnr, rp->u.range.first) &&
					 !SEQNR_GT (*cpsnr, rp->u.range.last))
					break;

			if (LIST_END (rwp->rw_changes, rp) ||
			    (rp->state != CS_MISSING 
#ifdef RTPS_FRAGMENTS
			       && !rp->fragments
#endif
			       			))
				return;
#ifdef RTPS_FRAGMENTS
			if (rp->fragments) {
				sfr_fragment (rwp, rp, fragp, finfo, hp, cp, ooo, ignore);
				return;
			}
#endif
			RW_SIGNAL (rwp, "REL-Data: in-range");
			RANGE_CHECK (&rwp->rw_changes, "REL-Data: in-range");
			if (SEQNR_GT (*cpsnr, rp->u.range.first)) {

				/* Prepend gap node: range.first .. *cpsnr -1 */
				gap_first = rp->u.range.first;
				gap_last = *cpsnr;
				SEQNR_DEC (gap_last);
				gap_rp = ccref_insert_gap (&rwp->rw_changes,
						           rp->prev,
						           &gap_first,
						           &gap_last,
							   CS_MISSING);
				if (!gap_rp)
					return;

				RW_SIGNAL (rwp, "REL-Data: prepend-gap");
			}
			if (SEQNR_LT (*cpsnr, rp->u.range.last)) {

				/* Append gap node: *cpsnr + 1 .. range.last */
				gap_first = *cpsnr;
				SEQNR_INC (gap_first);
				gap_last = rp->u.range.last;
				gap_rp = ccref_insert_gap (&rwp->rw_changes,
						           rp,
						           &gap_first,
						           &gap_last,
							   CS_MISSING);
				if (!gap_rp)
					return;

				RW_SIGNAL (rwp, "REL-Data: append-gap");
			}

			/* Reuse gap node for data. */
#ifdef RTPS_FRAGMENTS
			rp->fragments = NULL;
#endif
			if (ignore) {
				rp->relevant = 0;
				rp->u.range.first = *cpsnr;
				rp->u.range.last = *cpsnr;
			}
			else {
				if (cp->c_nrefs > 1) {
					ncp = hc_change_clone (cp);
					if (!ncp) {
						warn_printf ("sfr_rel_data (): out of memory for change clone!\r\n");
						return;
					}
				}
				else {
					rcl_access (cp);
					cp->c_nrefs++;
					rcl_done (cp);
					ncp = cp;
				}
				ncp->c_handle = h;
				ncp->c_seqnr = *cpsnr;
				rp->relevant = 1;
				rp->u.c.hci = hci;
				rp->u.c.change = ncp;
				rwp->rw_reader->data_queued++;
			}
			rp->state = CS_RECEIVED;
#ifdef RTPS_FRAGMENTS
			if (fragp) {
				sfr_fragment (rwp, rp, fragp, finfo, hp, cp, ooo, ignore);
				return;
			}
#endif
			RW_SIGNAL (rwp, "REL-Data: missing::received");
			RANGE_CHECK (&rwp->rw_changes, "REL-Data: missing::received");
		}

		/* If the received data sample caused some samples to be valid,
		   add these samples to the history cache and remove them from
		   the changes list. */
		rp = LIST_HEAD (rwp->rw_changes);
		if (rp &&
		    (rp->state == CS_RECEIVED || rp->state == CS_LOST) &&
#ifdef RTPS_FRAGMENTS
		    !rp->fragments &&
#endif
		    rwp->rw_heartbeats) {
			RW_SIGNAL (rwp, "REL-Data: process-samples");
			RANGE_CHECK (&rwp->rw_changes, "REL-Data: process-samples");
			sfr_process_samples (rwp);
		}
	}
Пример #9
0
LocatorNode_t *locator_list_add (LocatorList_t       *list,
				 LocatorKind_t       kind,
				 const unsigned char *addr,
				 uint32_t            port,
				 uint32_t            scope_id,
				 Scope_t             scope,
				 unsigned            flags,
				 unsigned            sproto)
{
	LocSearchData	data;
	LocatorNode_t	**npp, *np;
	LocatorRef_t	*rp, *p;
	int		is_new;

	data.kind = kind;
	data.addr = addr;
	data.port = port;

	lock_take (loc_lock);
	npp = sl_insert (&loc_list, &data, &is_new, loc_cmp);
	if (!npp) {
		warn_printf ("locator_list_add: not enough memory for list node!");
		lock_release (loc_lock);
		return (NULL);
	}
	if (is_new) {
		np = mds_pool_alloc (&mem_blocks [MB_LOCATOR]);
		if (!np) {
			warn_printf ("locator_list_add: not enough memory for locator node!");
#ifdef LIST_DELETE_NODE
			sl_delete_node (&loc_list, npp);
#else
			sl_delete (&loc_list, &data, loc_cmp);
#endif
			lock_release (loc_lock);
			return (NULL);
		}
		np->users = 0;
		np->locator.kind = kind;
		np->locator.port = port;
		memcpy (np->locator.address, addr, sizeof (np->locator.address));
		np->locator.scope_id = scope_id;
		np->locator.scope = scope;
		np->locator.flags = flags;
		np->locator.sproto = sproto;
		np->locator.intf = 0;
		np->locator.handle = 0;
		*npp = np;
	}
	else {
		np = *npp;
		if (np->locator.scope_id != scope_id ||
		    (np->locator.scope && scope && np->locator.scope != scope) ||
		    /*(np->locator.flags && flags && 
		     (np->locator.flags & LOCF_MFLAGS) != (flags & LOCF_MFLAGS)) ||*/
		    (np->locator.sproto && sproto && np->locator.sproto != sproto))
			log_printf (LOC_ID, 0, "locator_list_add: incompatible locator attributes for %s, "
						"%u:%u, %u:%u, 0x%x:0x%x, %u:%u!\r\n",
					locator_str (&np->locator),
					np->locator.scope_id, scope_id,
					np->locator.scope, scope,
					np->locator.flags, flags,
					np->locator.sproto, sproto);

		if (!np->locator.scope_id && scope_id)
			np->locator.scope_id = scope_id;
		if (!np->locator.scope && scope)
			np->locator.scope = scope;
		if (flags && np->locator.flags != flags)
			np->locator.flags |= flags;
		if (!np->locator.sproto && sproto)
			np->locator.sproto = sproto;

		/* Check if already in list. */
		for (rp = *list; rp; rp = rp->next)
			if (rp->data == np) {	/* Already there! */
				lock_release (loc_lock);
				return (0);
			}
	}
#ifdef LOG_LOCATORS
	log_printf (LOC_ID, 0, "LOC: locator_list_add (list=%p, %s)\r\n", (void *) list, locator_str (&np->locator));
#endif
	rp = mds_pool_alloc (&mem_blocks [MB_LOCREF]);
	if (!rp) {
		warn_printf ("locator_list_add: not enough memory for locator reference!\r\n");
		if (is_new) {
			mds_pool_free (&mem_blocks [MB_LOCATOR], np);
#ifdef LIST_DELETE_NODE
			sl_delete_node (&loc_list, npp);
#else
			sl_delete (&loc_list, &data, loc_cmp);
#endif
		}
		lock_release (loc_lock);
		return (NULL);
	}
	rp->next = NULL;
	rp->data = np;
	np->users++;
 	lock_release (loc_lock);
	if (*list) {
		for (p = *list; p->next; p = p->next)
			;
		p->next = rp;
	}
	else
		*list = rp;
	return (np);
}
Пример #10
0
DDS_ReturnCode_t dcps_write (DDS_DataWriter             wp,
			     const void                 *instance_data,
			     int                        dynamic,
			     const DDS_InstanceHandle_t handle,
			     const FTime_t              *time,
			     DDS_InstanceHandleSeq      *dests)
{
	Change_t		*cp;
	unsigned char		*keys;
	unsigned char		*dp;
	DB			*dbp;
	HCI			hci;
	size_t			tlen, ofs, size;
	InstanceHandle		h;
	const TypeSupport_t	*ts;
	unsigned		i;
	DDS_ReturnCode_t	ret;
	unsigned char		buf [16];

	prof_start (dcps_write_p);

	if (!writer_ptr (wp, 1, &ret))
		return (ret);

	if (dests) {
		if (!dests->_length || !dests->_buffer) {
			ret = DDS_RETCODE_BAD_PARAMETER;
			goto done;
		}
		else if (dests->_length > MAX_DW_DESTS) {
			ret = DDS_RETCODE_OUT_OF_RESOURCES;
			goto done;
		}
	}
	if (!wp->w_pm_status.current_count &&
	    wp->w_qos->qos.durability_kind == DDS_VOLATILE_DURABILITY_QOS &&
	    (wp->w_flags & EF_BUILTIN) == 0) {
		ret = DDS_RETCODE_OK;
		goto done;
	}

	h = handle;
	ts = wp->w_topic->type->type_support;
	if (!handle && ts->ts_keys) {
		keys = dcps_key_data_get (wp->w_topic, instance_data, dynamic, ENC_DATA (&wp->w_lep), buf, &size, &ret);
		if (!keys) {
			warn_printf ("DDS_DataWriter_write: invalid parameters!");
			goto done;
		}
		hci = hc_register (wp->w_cache, keys, size, time, &h);
		if (!hci) {
			warn_printf ("DDS_DataWriter_write: cache_register_instance() failed!");
			if (size > sizeof (buf))
				xfree (keys);

			ret = DDS_RETCODE_OUT_OF_RESOURCES;
			goto done;
		}
		if (size > sizeof (buf))
			xfree (keys);
	}
	else
		hci = NULL;

	if (!hc_write_required (wp->w_cache)) {
		ret = DDS_RETCODE_OK;
		goto done;
	}

	/* Allocate a new change record. */
	cp = hc_change_new ();
	if (!cp) {
		ret = DDS_RETCODE_OUT_OF_RESOURCES;
		goto done;
	}
#if defined (DDS_DEBUG) && defined (DUMP_DDATA)
	if (dynamic) {
		dbg_printf ("dcps_write:\r\n");
		xd_dump (1, instance_data);
	}
#endif
	if (ts->ts_dynamic || ts->ts_length > 512) {
		ofs = 0;
		tlen = DDS_MarshalledDataSize (instance_data, dynamic, ts, &ret);
		if (ret) {
			log_printf (DCPS_ID, 0, "DDS_DataWriter_write({%u}): marshalled buffer size could not be determined (%d)!\r\n", 
						wp->w_handle, ret);
			goto free_data;
		}
		if (tlen > dds_max_sample_size) {
			log_printf (DCPS_ID, 0, "DDS_DataWriter_write({u}): marshalled buffer size exceeds system limits (%lu/%lu bytes)\r\n",
						(unsigned long) tlen, (unsigned long) dds_max_sample_size);
			ret = DDS_RETCODE_OUT_OF_RESOURCES;
			goto free_data;
		}
	}
	else {
		if (ts->ts_length > dds_max_sample_size) {
			log_printf (DCPS_ID, 0, "DDS_DataWriter_write({u}): sample size exceeds system limits (%lu/%lu bytes)\r\n",
						(unsigned long) ts->ts_length, (unsigned long) dds_max_sample_size);
			ret = DDS_RETCODE_OUT_OF_RESOURCES;
			goto free_data;
		}
		ofs = 4;
		tlen = ts->ts_length + 4;
		if (tlen <= C_DSIZE) {
			cp->c_db = NULL;
			dp = cp->c_xdata;
			memcpy (dp + ofs, instance_data, ts->ts_length);
			dp [0] = dp [2] = dp [3] = 0;
			dp [1] = (MODE_RAW << 1) | ENDIAN_CPU;
			goto data_copied;
		}
	}

	/* Allocate a container to store the data. */
	if ((dbp = db_alloc_data (tlen, 1)) == NULL) {
		warn_printf ("DDS_DataWriter_write({%u}): out of memory for data (%lu bytes)!\r\n",
					wp->w_handle, (unsigned long) tlen);
		ret = DDS_RETCODE_OUT_OF_RESOURCES;
		goto free_data;
	}
	cp->c_db = dbp;
	dp = dbp->data;
	if (ts->ts_dynamic || ts->ts_length > 512) {

		/* Add marshalled data to DB chain, prefixed with marshalling type. */
		ret = DDS_MarshallData (dp, instance_data, dynamic, ts);
		if (ret) {
			log_printf (DCPS_ID, 0, "DDS_DataWriter_write({%u}): error %u marshalling data!\r\n",
					wp->w_handle, ret);
			goto free_data;
		}
	}
	else {
		/* Add raw data to DB chain, prefixed with RAW identifier. */
		db_put_data (dbp, 4, instance_data, ts->ts_length);
		dp [0] = dp [2] = dp [3] = 0;
		dp [1] = (MODE_RAW << 1) | ENDIAN_CPU;
	}

    data_copied:
	cp->c_data = dp;

     /*	cp->c_wack = 0; */
	cp->c_kind = ALIVE;
	cp->c_linear = 1;
	cp->c_writer = wp->w_handle;
	cp->c_time = *time;
	cp->c_handle = h;
	cp->c_length = tlen;
	if (!dests)
		cp->c_dests [0] = 0;
	else {
		for (i = 0; i < dests->_length; i++)
			cp->c_dests [i] = dests->_buffer [i];
		while (i < MAX_DW_DESTS)
			cp->c_dests [i++] = 0;
	}
	ret = hc_add_inst (wp->w_cache, cp, hci, 0);
	goto done;

    free_data:
    	hc_change_free (cp);

    done:
	lock_release (wp->w_lock);
	prof_stop (dcps_write_p, 1);
	return (ret);
}
Пример #11
0
void sedp_publication_event (Reader_t *rp,
			     NotificationType_t t,
			     int cdd,
			     int secure)
{
	Domain_t		*dp = rp->r_subscriber->domain;
	Participant_t		*pp;
	ChangeData_t		change;
	DiscoveredWriterData	*info = NULL, tinfo;
	Topic_t			*tp;
	DiscoveredWriter_t	*dwp;
	Reader_t		*mrp;
	UniQos_t		qos;
	InfoType_t		type;
	GUID_t			*guidp;
	int			error;

	if (t != NT_DATA_AVAILABLE)
		return;

	rp->r_status &= ~DDS_DATA_AVAILABLE_STATUS;
	for (;;) {
		if (info) {
			pid_writer_data_cleanup (info);
			xfree (info);
			info = NULL;
		}
		/*dtrc_print0 ("SEDP-Pub: get samples ");*/
		error = disc_get_data (rp, &change);
		if (error) {
			/*dtrc_print0 ("- none\r\n");*/
			break;
		}
		/*dtrc_print1 ("- valid(%u)\r\n", change.kind);*/
		if (change.kind != ALIVE) {
			error = hc_get_key (rp->r_cache, change.h, &tinfo, 0);
			if (error)
				continue;

			guidp = &tinfo.proxy.guid;
			type = EI_DELETE;
			hc_inst_free (rp->r_cache, change.h);
		}
		else {
			info = change.data;
			if (!info->topic_name || !info->type_name) {
				hc_inst_free (rp->r_cache, change.h);
				continue;
			}
			type = EI_NEW;
			guidp = &info->proxy.guid;
		}
			pp = entity_participant (change.writer);
		if (!pp ||				/* Not found. */
		    pp == &dp->participant ||		/* Own sent info. */
		    entity_ignored (pp->p_flags)) {	/* Ignored. */
			if (pp != &dp->participant && !cdd)
				warn_printf ("sedp_publication_rx: invalid change.writer field!\r\n");

			hc_inst_free (rp->r_cache, change.h);
			dtrc_print0 ("SEDP-Pub: unneeded!\r\n");
			continue;	/* Filter out unneeded info. */
		}

		/* Publication from remote participant. */
		if (type == EI_DELETE) {
			dwp = (DiscoveredWriter_t *) endpoint_lookup (pp,
							&guidp->entity_id);
			if (!dwp) {
				dtrc_print0 ("SEDP-Pub: DELETE && doesn't exist!\r\n");
				continue; /* If doesn't exist - no action. */
			}
			if (!dwp->dw_topic) {
				endpoint_delete (pp, &dwp->dw_ep);
				continue; /* Ignored topic -- only endpoint. */
			}
			if (sedp_log)
				log_printf (SEDP_ID, 0, "SEDP: Deleted %spublication (%s/%s) from peer!\r\n",
						(secure) ? "secure " : "",
						str_ptr (dwp->dw_topic->name),
						str_ptr (dwp->dw_topic->type->type_name));
			disc_publication_remove (pp, dwp);

			hc_inst_free (rp->r_cache, change.h);
			continue;
		}

		/* Do we know this topic? */
		tp = topic_lookup (&dp->participant, str_ptr (info->topic_name));
		if (tp && entity_ignored (tp->entity.flags)) {
			hc_inst_free (rp->r_cache, change.h);
			dtrc_print1 ("SEDP: ignored topic (%s)!\r\n", str_ptr (info->topic_name));
			continue;	/* Ignored topic. */
		}

		/* Do we know this endpoint already? */
		dwp = (DiscoveredWriter_t *) endpoint_lookup (pp, &guidp->entity_id);
		if (dwp) {
			if (entity_ignored (dwp->dw_flags) || cdd) {
				hc_inst_free (rp->r_cache, change.h);
				continue; /* Ignored endpoint. */
			}
			dtrc_print1 ("Already exists (%s)!\r\n", str_ptr (info->topic_name));
			type = EI_UPDATE;
			disc_publication_update (pp, dwp, info);
			if (sedp_log)
				log_printf (SEDP_ID, 0, "SEDP: Updated %spublication (%s/%s) from peer!\r\n",
						(secure) ? "secure " : "",
						str_ptr (info->topic_name),
						str_ptr (info->type_name));
			hc_inst_free (rp->r_cache, change.h);
		}
		else {
			/* Get QoS parameters. */
			qos_disc_writer_set (&qos, &info->qos);
			mrp = NULL;
			/* Create new endpoint. */
			dwp = (DiscoveredWriter_t *) endpoint_create (pp,
					pp, &guidp->entity_id, NULL);
			if (!dwp) {
				dtrc_print1 ("SEDP: Create endpoint (%s) not possible - exit!\r\n", str_ptr (info->topic_name));
				hc_inst_free (rp->r_cache, change.h);
				qos_disc_writer_restore (&info->qos, &qos);
				continue;  /* Can't create -- just ignore. */
			}
			disc_publication_add (pp, dwp, &qos, tp, mrp, info);
			hc_inst_free (rp->r_cache, change.h);
			if (sedp_log)
				log_printf (SEDP_ID, 0, "SEDP: New %spublication (%s/%s) from %s!\r\n",
						(secure) ? "secure " : "",
						str_ptr (info->topic_name),
						str_ptr (info->type_name),
						(cdd) ? "CDD" : "peer");

		}
	}
	if (info) {
		pid_writer_data_cleanup (info);
		xfree (info);
	}
}