Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base64.c2
-rw-r--r--base64.h2
-rw-r--r--breakpoints.c2
-rw-r--r--breakpoints.h2
-rw-r--r--channel.c2
-rw-r--r--channel.h2
-rw-r--r--channel_tcp.c1488
-rw-r--r--channel_tcp.h62
-rw-r--r--cmdline.c2
-rw-r--r--cmdline.h2
-rw-r--r--config.h2
-rw-r--r--context.c2
-rw-r--r--context.h2
-rw-r--r--diagnostics.c2
-rw-r--r--diagnostics.h2
-rw-r--r--discovery.c526
-rw-r--r--discovery.h112
-rw-r--r--discovery_help.c212
-rw-r--r--discovery_help.h50
-rw-r--r--discovery_udp.c826
-rw-r--r--discovery_udp.h48
-rw-r--r--dwarf.h2
-rw-r--r--dwarfio.c2
-rw-r--r--dwarfio.h2
-rw-r--r--elf.c2
-rw-r--r--elf.h2
-rw-r--r--errors.c2
-rw-r--r--errors.h2
-rw-r--r--events.c2
-rw-r--r--events.h2
-rw-r--r--exceptions.c2
-rw-r--r--exceptions.h2
-rw-r--r--expressions.c2
-rw-r--r--expressions.h2
-rw-r--r--filesystem.c2
-rw-r--r--filesystem.h2
-rw-r--r--ip_ifc.c182
-rw-r--r--ip_ifc.h60
-rw-r--r--json.c2
-rw-r--r--json.h2
-rw-r--r--linenumbers.c2
-rw-r--r--linenumbers.h2
-rw-r--r--link.h2
-rw-r--r--main.c2
-rw-r--r--main_client.c258
-rw-r--r--main_reg.c252
-rw-r--r--mdep.c2
-rw-r--r--mdep.h2
-rw-r--r--memory.c2
-rw-r--r--memory.h2
-rw-r--r--myalloc.c2
-rw-r--r--myalloc.h2
-rw-r--r--peer.c514
-rw-r--r--peer.h144
-rw-r--r--processes.c2
-rw-r--r--processes.h2
-rw-r--r--protocol.c2
-rw-r--r--protocol.h2
-rw-r--r--proxy.c2
-rw-r--r--proxy.h2
-rw-r--r--registers.c2
-rw-r--r--registers.h2
-rw-r--r--runctrl.c2
-rw-r--r--runctrl.h2
-rw-r--r--stacktrace.c2
-rw-r--r--stacktrace.h2
-rw-r--r--streams.c2
-rw-r--r--streams.h2
-rw-r--r--symbols.c2
-rw-r--r--symbols.h2
-rw-r--r--sysmon.c2
-rw-r--r--sysmon.h2
-rw-r--r--tcf.h2
-rw-r--r--test.c2
-rw-r--r--test.h2
-rw-r--r--trace.c2
-rw-r--r--trace.h2
77 files changed, 2430 insertions, 2430 deletions
diff --git a/base64.c b/base64.c
index 4c5fc7a4..ef52384c 100644
--- a/base64.c
+++ b/base64.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/base64.h b/base64.h
index 94e182c4..f9417e9b 100644
--- a/base64.h
+++ b/base64.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/breakpoints.c b/breakpoints.c
index aee8f7dc..b552ce0c 100644
--- a/breakpoints.c
+++ b/breakpoints.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/breakpoints.h b/breakpoints.h
index c67855f9..b5329546 100644
--- a/breakpoints.h
+++ b/breakpoints.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/channel.c b/channel.c
index 118b2418..683d85de 100644
--- a/channel.c
+++ b/channel.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/channel.h b/channel.h
index d49e52d7..6fa3a167 100644
--- a/channel.h
+++ b/channel.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/channel_tcp.c b/channel_tcp.c
index eee09852..54130af7 100644
--- a/channel_tcp.c
+++ b/channel_tcp.c
@@ -1,744 +1,744 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Implements input and output stream over TCP/IP transport.
- */
-
-#if defined(_WRS_KERNEL)
-# include <vxWorks.h>
-#endif
-#include <stddef.h>
-#include <errno.h>
-#include <assert.h>
-#include "mdep.h"
-#include "tcf.h"
-#include "channel.h"
-#include "channel_tcp.h"
-#include "myalloc.h"
-#include "protocol.h"
-#include "events.h"
-#include "exceptions.h"
-#include "trace.h"
-#include "json.h"
-#include "peer.h"
-#include "ip_ifc.h"
-
-#define ESC 3
-#define BUF_SIZE 0x1000
-#define CHANNEL_MAGIC 0x87208956
-#define REFRESH_TIME 15
-#define STALE_TIME_DELTA (REFRESH_TIME * 2)
-#define MAX_IFC 10
-
-#define is_suspended(CH) ((CH)->chan.spg && (CH)->chan.spg->suspended)
-
-typedef struct ChannelTCP ChannelTCP;
-
-struct ChannelTCP {
- Channel chan; /* Public channel information - must be first */
- int magic; /* Magic number */
- int socket; /* Socket file descriptor */
- pthread_t thread; /* Socket receiving thread */
- int thread_exited;
- pthread_mutex_t mutex; /* Channel data access synchronization lock */
- pthread_cond_t signal;
- int long_msg; /* Message is longer then buffer, handlig should start before receiving EOM */
- int waiting_space; /* Receiving thread is waiting for buffer space */
- int waiting_data; /* Dispatch thread is waiting for data to read (long messages only) */
- int message_count; /* Number of messages waiting to be dispatched */
- int event_posted; /* Message handling event is posted to event queue */
- int lock_cnt; /* Stream lock count, when > 0 channel cannot be deleted */
- int handling_msg; /* Stream mutex is locked for input message handling */
-
- /* Input stream buffer */
- unsigned char ibuf[BUF_SIZE];
- int ibuf_inp;
- int ibuf_out;
- int eof;
- int peek;
-
- /* Output stream state */
- char obuf[BUF_SIZE];
- int obuf_inp;
- int out_errno;
-};
-
-typedef struct ServerTCP ServerTCP;
-
-struct ServerTCP {
- ChannelServer serv;
- int sock;
- TCFSuspendGroup * spg;
- TCFBroadcastGroup * bcg;
- pthread_t server_thread;
- PeerServer * ps;
- LINK servlink;
-};
-
-#define channel2tcp(A) ((ChannelTCP *)((char *)(A) - offsetof(ChannelTCP, chan)))
-#define inp2channel(A) ((Channel *)((char *)(A) - offsetof(Channel, inp)))
-#define out2channel(A) ((Channel *)((char *)(A) - offsetof(Channel, out)))
-#define server2tcp(A) ((ServerTCP *)((char *)(A) - offsetof(ServerTCP, serv)))
-#define servlink2tcp(A) ((ServerTCP *)((char *)(A) - offsetof(ServerTCP, servlink)))
-
-static ChannelCloseListener close_listeners[16];
-static int close_listeners_cnt = 0;
-static LINK server_list;
-
-static void delete_channel(ChannelTCP * c) {
- int i;
- trace(LOG_PROTOCOL, "Deleting channel 0x%08x", c);
- assert(c->lock_cnt == 0);
- assert(c->magic == CHANNEL_MAGIC);
- c->chan.cb->disconnected(&c->chan);
- for (i = 0; i < close_listeners_cnt; i++) {
- close_listeners[i](&c->chan);
- }
- if (c->chan.bcg) list_remove(&c->chan.bclink);
- if (c->chan.spg) list_remove(&c->chan.susplink);
- c->magic = 0;
- loc_free(c);
-}
-
-static void tcp_lock(Channel * c) {
- ChannelTCP * channel = channel2tcp(c);
- assert(is_dispatch_thread());
- assert(channel->magic == CHANNEL_MAGIC);
- channel->lock_cnt++;
-}
-
-static void tcp_unlock(Channel * c) {
- ChannelTCP * channel = channel2tcp(c);
- assert(is_dispatch_thread());
- assert(channel->magic == CHANNEL_MAGIC);
- assert(channel->lock_cnt > 0);
- channel->lock_cnt--;
- if (channel->lock_cnt == 0) delete_channel(channel);
-}
-
-static int tcp_is_closed(Channel * c) {
- ChannelTCP * channel = channel2tcp(c);
- assert(is_dispatch_thread());
- assert(channel->magic == CHANNEL_MAGIC);
- assert(channel->lock_cnt > 0);
- return channel->socket < 0;
-}
-
-static void flush_stream(OutputStream * out) {
- int cnt = 0;
- ChannelTCP * channel = channel2tcp(out2channel(out));
- assert(is_dispatch_thread());
- assert(channel->magic == CHANNEL_MAGIC);
- if (channel->obuf_inp == 0) return;
- if (channel->socket < 0) return;
- if (channel->out_errno) return;
- while (cnt < channel->obuf_inp) {
- int wr = send(channel->socket, channel->obuf + cnt, channel->obuf_inp - cnt, 0);
- if (wr < 0) {
- int err = errno;
- trace(LOG_PROTOCOL, "Can't sent() on channel 0x%08x: %d %s", channel, err, errno_to_str(err));
- channel->out_errno = err;
- return;
- }
- cnt += wr;
- }
- assert(cnt == channel->obuf_inp);
- channel->obuf_inp = 0;
-}
-
-static void write_stream(OutputStream * out, int byte) {
- ChannelTCP * channel = channel2tcp(out2channel(out));
- int b0 = byte;
- assert(is_dispatch_thread());
- assert(channel->magic == CHANNEL_MAGIC);
- if (channel->socket < 0) return;
- if (channel->out_errno) return;
- if (b0 < 0) byte = ESC;
- channel->obuf[channel->obuf_inp++] = byte;
- if (channel->obuf_inp == BUF_SIZE) flush_stream(out);
- if (b0 < 0 || b0 == ESC) {
- if (b0 == ESC) byte = 0;
- else if (b0 == MARKER_EOM) byte = 1;
- else if (b0 == MARKER_EOS) byte = 2;
- else assert(0);
- if (channel->socket < 0) return;
- if (channel->out_errno) return;
- channel->obuf[channel->obuf_inp++] = byte;
- if (channel->obuf_inp == BUF_SIZE) flush_stream(out);
- }
-}
-
-static int read_byte(ChannelTCP * channel) {
- int res;
- assert(channel->message_count > 0);
- while (channel->ibuf_inp == channel->ibuf_out) {
- assert(channel->long_msg);
- assert(channel->message_count == 1);
- if (channel->waiting_space) {
- assert(!channel->waiting_data);
- pthread_cond_signal(&channel->signal);
- channel->waiting_space = 0;
- }
- if (channel->eof) return MARKER_EOS;
- if (channel->socket < 0) return MARKER_EOS;
- assert(!channel->waiting_data);
- assert(!channel->waiting_space);
- channel->waiting_data = 1;
- pthread_cond_wait(&channel->signal, &channel->mutex);
- assert(!channel->waiting_data);
- }
- res = channel->ibuf[channel->ibuf_out];
- channel->ibuf_out = (channel->ibuf_out + 1) % BUF_SIZE;
- return res;
-}
-
-static int read_stream(InputStream * inp) {
- int b;
- ChannelTCP * c = channel2tcp(inp2channel(inp));
-
- assert(is_dispatch_thread());
- assert(c->magic == CHANNEL_MAGIC);
-
- if (c->peek != MARKER_NULL) {
- assert(c->peek != MARKER_EOM);
- b = c->peek;
- c->peek = MARKER_NULL;
- }
- else {
- if (!c->handling_msg) {
- pthread_mutex_lock(&c->mutex);
- c->handling_msg = 1;
- }
- b = read_byte(c);
- if (b == ESC) {
- b = read_byte(c);
- if (b == 0) {
- b = ESC;
- }
- else if (b == 1) {
- b = MARKER_EOM;
- c->message_count--;
- if (c->waiting_space) {
- assert(!c->waiting_data);
- pthread_cond_signal(&c->signal);
- c->waiting_space = 0;
- }
- pthread_mutex_unlock(&c->mutex);
- c->handling_msg = 0;
- }
- else if (b == 2) {
- b = MARKER_EOS;
- }
- }
- }
-
- return b;
-}
-
-static int peek_stream(InputStream * inp) {
- ChannelTCP * c = channel2tcp(inp2channel(inp));
- return c->peek = read_stream(inp);
-}
-
-static void send_eof_and_close(Channel * channel, int err) {
- ChannelTCP * c = channel2tcp(channel);
- assert(c->magic == CHANNEL_MAGIC);
- write_stream(&c->chan.out, MARKER_EOS);
- write_errno(&c->chan.out, err);
- c->chan.out.write(&c->chan.out, MARKER_EOM);
- c->chan.out.flush(&c->chan.out);
- trace(LOG_PROTOCOL, "Closing socket, channel 0x%08x", c);
- closesocket(c->socket);
- c->socket = -1;
-}
-
-static void handle_channel_msg(void * x) {
- Trap trap;
- ChannelTCP * c = (ChannelTCP *)x;
- assert(is_dispatch_thread());
- for (;;) {
- assert(c->magic == CHANNEL_MAGIC);
- if (!c->handling_msg) {
- pthread_mutex_lock(&c->mutex);
- c->handling_msg = 1;
- }
- assert(c->event_posted);
- if (c->thread_exited && (c->socket < 0 || c->message_count == 0 || c->long_msg)) {
- void * res = NULL;
- c->event_posted = 0;
- c->handling_msg = 0;
- pthread_mutex_unlock(&c->mutex);
- if (c->thread) pthread_join(c->thread, &res);
- if (c->socket >= 0) send_eof_and_close(&c->chan, 0);
- tcp_unlock(&c->chan);
- return;
- }
- if (c->message_count == 0 || is_suspended(c)) {
- c->event_posted = 0;
- c->handling_msg = 0;
- pthread_mutex_unlock(&c->mutex);
- break;
- }
- if (set_trap(&trap)) {
- c->chan.cb->receive(&c->chan);
- clear_trap(&trap);
- }
- else {
- trace(LOG_ALWAYS, "Exception handling protocol message: %d %s",
- trap.error, errno_to_str(trap.error));
- c->peek = MARKER_NULL;
- c->ibuf_out = c->ibuf_inp;
- c->message_count = 0;
- send_eof_and_close(&c->chan, trap.error);
- }
- }
- if (c->chan.bcg) {
- c->chan.bcg->out.flush(&c->chan.bcg->out);
- }
- else {
- c->chan.out.flush(&c->chan.out);
- }
-}
-
-static void channel_check_pending(Channel * c) {
- ChannelTCP * channel = channel2tcp(c);
- assert(is_dispatch_thread());
- if (!is_suspended(channel)) {
- pthread_mutex_lock(&channel->mutex);
- if (channel->message_count > 0 && !channel->event_posted) {
- post_event(handle_channel_msg, channel);
- channel->event_posted = 1;
- }
- pthread_mutex_unlock(&channel->mutex);
- }
-}
-
-static int channel_get_message_count(Channel * c) {
- ChannelTCP * channel = channel2tcp(c);
- int cnt;
- assert(is_dispatch_thread());
- pthread_mutex_lock(&channel->mutex);
- cnt = channel->message_count;
- pthread_mutex_unlock(&channel->mutex);
- return cnt;
-}
-
-static void * stream_socket_handler(void * x) {
- int i;
- int esc = 0;
- ChannelTCP * channel = (ChannelTCP *)x;
- unsigned char pkt[BUF_SIZE];
-
- pthread_mutex_lock(&channel->mutex);
- while (!channel->eof && channel->socket >= 0) {
- int err = 0;
- int rd = 0;
-
- pthread_mutex_unlock(&channel->mutex);
- rd = recv(channel->socket, (void *)pkt, sizeof(pkt), 0);
- err = errno;
- assert(channel->magic == CHANNEL_MAGIC);
- pthread_mutex_lock(&channel->mutex);
-
- if (rd < 0) {
- trace(LOG_ALWAYS, "Can't read from socket: %s", errno_to_str(errno));
- if (channel->socket < 0) break;
- channel->eof = 1;
- break;
- }
-
- if (rd == 0) {
- trace(LOG_PROTOCOL, "Socket is shutdown by remote peer, channel 0x%08x", channel);
- channel->eof = 1;
- break;
- }
-
- for (i = 0; i < rd && !channel->eof; i++) {
- unsigned char ch = pkt[i];
- int ibuf_next = (channel->ibuf_inp + 1) % BUF_SIZE;
- while (ibuf_next == channel->ibuf_out) {
- if (channel->message_count == 0 && !channel->long_msg) {
- channel->long_msg = 1;
- channel->message_count = 1;
- if (!is_suspended(channel) && !channel->event_posted) {
- post_event(handle_channel_msg, channel);
- channel->event_posted = 1;
- }
- }
- assert(channel->message_count > 0);
- assert(!channel->waiting_data);
- assert(!channel->waiting_space);
- channel->waiting_space = 1;
- pthread_cond_wait(&channel->signal, &channel->mutex);
- assert(ibuf_next == (channel->ibuf_inp + 1) % BUF_SIZE);
- assert(!channel->waiting_space);
- }
- if (esc) {
- esc = 0;
- switch (ch) {
- case 0:
- /* ESC byte */
- break;
- case 1:
- /* EOM - End Of Message */
- if (channel->long_msg) {
- channel->long_msg = 0;
- assert(channel->message_count == 1);
- }
- else {
- channel->message_count++;
- if (!is_suspended(channel) && !channel->event_posted) {
- post_event(handle_channel_msg, channel);
- channel->event_posted = 1;
- }
- }
- break;
- case 2:
- /* EOS - End Of Stream */
- trace(LOG_PROTOCOL, "End of stream on channel 0x%08x", channel);
- channel->eof = 1;
- break;
- default:
- /* Invalid escape sequence */
- trace(LOG_ALWAYS, "Protocol: Invalid escape sequence");
- channel->eof = 1;
- ch = 2;
- break;
- }
- }
- else {
- esc = ch == ESC;
- }
- channel->ibuf[channel->ibuf_inp] = ch;
- channel->ibuf_inp = ibuf_next;
- if (channel->waiting_data) {
- assert(!channel->waiting_space);
- pthread_cond_signal(&channel->signal);
- channel->waiting_data = 0;
- }
- }
- }
- if (channel->waiting_data) {
- assert(!channel->waiting_space);
- pthread_cond_signal(&channel->signal);
- channel->waiting_data = 0;
- }
- if (!channel->event_posted) {
- post_event(handle_channel_msg, channel);
- channel->event_posted = 1;
- }
- channel->thread_exited = 1;
- pthread_mutex_unlock(&channel->mutex);
- return NULL;
-}
-
-static ChannelTCP * create_channel(int sock) {
- const int i = 1;
- ChannelTCP * c;
-
- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&i, sizeof(i)) < 0) {
- trace(LOG_ALWAYS, "Can't set TCP_NODELAY option on a socket: %s", errno_to_str(errno));
- closesocket(sock);
- return NULL;
- }
-
- c = loc_alloc_zero(sizeof *c);
- c->magic = CHANNEL_MAGIC;
- pthread_mutex_init(&c->mutex, NULL);
- pthread_cond_init(&c->signal, NULL);
- c->chan.inp.read = read_stream;
- c->chan.inp.peek = peek_stream;
- c->chan.out.write = write_stream;
- c->chan.out.flush = flush_stream;
- c->chan.check_pending = channel_check_pending;
- c->chan.message_count = channel_get_message_count;
- c->chan.lock = tcp_lock;
- c->chan.unlock = tcp_unlock;
- c->chan.is_closed = tcp_is_closed;
- c->chan.close = send_eof_and_close;
- c->socket = sock;
- c->peek = MARKER_NULL;
- return c;
-}
-
-static void start_channel(ChannelTCP * c) {
- int error;
-
- if (c->chan.spg) list_add_last(&c->chan.susplink, &c->chan.spg->channels);
- if (c->chan.bcg) list_add_last(&c->chan.bclink, &c->chan.bcg->channels);
-
- tcp_lock(&c->chan);
- trace(LOG_PROTOCOL, "Starting channel 0x%08x", c);
-
- c->chan.cb->connecting(&c->chan);
-
- error = pthread_create(&c->thread, &pthread_create_attr, stream_socket_handler, c);
- if (error) {
- trace(LOG_ALWAYS, "Can't create a thread: %d %s", error, errno_to_str(error));
- send_eof_and_close(&c->chan, 0);
- tcp_unlock(&c->chan);
- }
-}
-
-static void refresh_peer_server(int sock, PeerServer * ps) {
- int i;
- PeerServer * ps2;
- struct sockaddr_in sin;
-#if defined(_WRS_KERNEL)
- int sinlen;
-#else
- socklen_t sinlen;
-#endif
- char *transport;
- char *str_host;
- char str_port[32];
- char str_id[64];
- int ifcind;
- struct in_addr src_addr;
- ip_ifc_info ifclist[MAX_IFC];
-
- sinlen = sizeof sin;
- if (getsockname(sock, (struct sockaddr *)&sin, &sinlen) != 0) {
- trace(LOG_ALWAYS, "refresh_peer_server: getsockname error: %s", errno_to_str(errno));
- return;
- }
- ifcind = build_ifclist(sock, MAX_IFC, ifclist);
- while (ifcind-- > 0) {
- if (sin.sin_addr.s_addr != INADDR_ANY &&
- (ifclist[ifcind].addr & ifclist[ifcind].mask) !=
- (sin.sin_addr.s_addr & ifclist[ifcind].mask)) {
- continue;
- }
- src_addr.s_addr = ifclist[ifcind].addr;
- ps2 = peer_server_alloc();
- ps2->flags = ps->flags | PS_FLAG_LOCAL | PS_FLAG_DISCOVERABLE;
- for (i = 0; i < ps->ind; i++) {
- peer_server_addprop(ps2, loc_strdup(ps->list[i].name), loc_strdup(ps->list[i].value));
- }
- transport = peer_server_getprop(ps2, "TransportName", NULL);
- assert(transport != NULL);
- snprintf(str_port, sizeof(str_port), "%d", ntohs(sin.sin_port));
- str_host = loc_strdup(inet_ntoa(src_addr));
- snprintf(str_id, sizeof(str_id), "%s:%s:%s", transport, str_host, str_port);
- peer_server_addprop(ps2, loc_strdup("ID"), loc_strdup(str_id));
- peer_server_addprop(ps2, loc_strdup("Host"), str_host);
- peer_server_addprop(ps2, loc_strdup("Port"), loc_strdup(str_port));
- peer_server_add(ps2, STALE_TIME_DELTA);
- }
-}
-
-static void refresh_all_peer_server(void *x) {
- LINK * l;
-
- if (list_is_empty(&server_list)) {
- return;
- }
- l = server_list.next;
- while (l != &server_list) {
- ServerTCP * si = servlink2tcp(l);
- refresh_peer_server(si->sock, si->ps);
- l = l->next;
- }
- post_event_with_delay(refresh_all_peer_server, NULL, REFRESH_TIME*1000*1000);
-}
-
-struct NewChannelInfo {
- int sock;
- ServerTCP * si;
-};
-
-static void handle_channel_open(void * x) {
- struct NewChannelInfo * i = x;
- ChannelTCP * c;
-
- c = create_channel(i->sock);
- i->si->serv.cb->newConnection(&i->si->serv, &c->chan);
- start_channel(c);
- loc_free(i);
-}
-
-static void * tcp_server_socket_handler(void * x) {
- ServerTCP * si = x;
-
- while (si->sock >= 0) {
- struct NewChannelInfo *i;
- int sock = accept(si->sock, NULL, NULL);
- if (sock < 0) {
- if (si->sock < 0) {
- break;
- }
- trace(LOG_ALWAYS, "socket accept failed: %d %s", errno, errno_to_str(errno));
- continue;
- }
- i = loc_alloc(sizeof *i);
- i->sock = sock;
- i->si = si;
- post_event(handle_channel_open, i);
- }
- loc_free(si);
- return 0;
-}
-
-static void server_close(ChannelServer * serv) {
- ServerTCP * s = server2tcp(serv);
-
- assert(is_dispatch_thread());
- if (s->sock < 0) {
- return;
- }
- list_remove(&s->servlink);
- peer_server_free(s->ps);
- closesocket(s->sock);
- s->sock = -1;
-}
-
-ChannelServer * channel_tcp_server(PeerServer * ps, ChannelServerCallbacks * cb, void * client_data) {
- const int i = 1;
- int sock;
- int error;
- char * reason = NULL;
- struct addrinfo hints;
- struct addrinfo * reslist = NULL;
- struct addrinfo * res = NULL;
- ServerTCP * si;
- char * host = peer_server_getprop(ps, "Host", NULL);
- char * port = peer_server_getprop(ps, "Port", "");
-
- assert(is_dispatch_thread());
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_flags = AI_PASSIVE;
- error = loc_getaddrinfo(host, port, &hints, &reslist);
- if (error) {
- trace(LOG_ALWAYS, "getaddrinfo error: %s", loc_gai_strerror(error));
- return NULL;
- }
- sock = -1;
- reason = NULL;
- for (res = reslist; res != NULL; res = res->ai_next) {
- sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (sock < 0) {
- error = errno;
- reason = "create";
- continue;
- }
- /* Allow rapid reuse of this port. */
- if (((struct sockaddr_in *)res->ai_addr)->sin_port != 0 &&
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i)) < 0) {
- error = errno;
- reason = "setsockopt(reuse) for";
- closesocket(sock);
- sock = -1;
- continue;
- }
- if (bind(sock, res->ai_addr, res->ai_addrlen)) {
- error = errno;
- reason = "bind";
- closesocket(sock);
- sock = -1;
- continue;
- }
- if (listen(sock, 16)) {
- error = errno;
- reason = "listen on";
- closesocket(sock);
- sock = -1;
- continue;
- }
-
- /* Only create one listener - don't see how getaddrinfo with
- * the given arguments could return more then one anyway */
- break;
- }
- loc_freeaddrinfo(reslist);
- if (sock < 0) {
- trace(LOG_ALWAYS, "socket %s error: %s", reason, errno_to_str(error));
- return NULL;
- }
- si = loc_alloc(sizeof *si);
- si->serv.client_data = client_data;
- si->serv.cb = cb;
- si->serv.close = server_close;
- si->sock = sock;
- si->ps = ps;
- if (server_list.next == NULL) list_init(&server_list);
- if (list_is_empty(&server_list)) {
- post_event_with_delay(refresh_all_peer_server, NULL, REFRESH_TIME * 1000 * 1000);
- }
- list_add_last(&si->servlink, &server_list);
- refresh_peer_server(sock, ps);
- if (pthread_create(&si->server_thread, &pthread_create_attr, tcp_server_socket_handler, si) != 0) {
- perror("Can't create socket listener thread");
- return NULL;
- }
- return &si->serv;
-}
-
-Channel * channel_tcp_connect(PeerServer * ps, ChannelCallbacks * cb,
- void * client_data, TCFSuspendGroup * spg, TCFBroadcastGroup * bcg) {
- const int i = 1;
- int sock = -1;
- ChannelTCP * c = NULL;
- int error = 0;
- char * reason = NULL;
- char * host = peer_server_getprop(ps, "Host", NULL);
- char * port = peer_server_getprop(ps, "Port", NULL);
- struct addrinfo hints;
- struct addrinfo * reslist = NULL;
- struct addrinfo * res = NULL;
-
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- error = loc_getaddrinfo(host, port, &hints, &reslist);
- if (error) {
- trace(LOG_ALWAYS, "getaddrinfo error: %s", loc_gai_strerror(error));
- return NULL;
- }
- sock = -1;
- reason = NULL;
- for (res = reslist; res != NULL; res = res->ai_next) {
- sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (sock < 0) {
- error = errno;
- reason = "create";
- continue;
- }
- if (connect(sock, res->ai_addr, res->ai_addrlen)) {
- error = errno;
- reason = "connect";
- closesocket(sock);
- sock = -1;
- continue;
- }
- break;
- }
- loc_freeaddrinfo(reslist);
- if (sock < 0) {
- trace(LOG_ALWAYS, "socket %s error: %s", reason, errno_to_str(error));
- return NULL;
- }
-
- c = create_channel(sock);
- if (c == NULL) {
- return NULL;
- }
- c->chan.cb = cb;
- c->chan.client_data = client_data;
- c->chan.spg = spg;
- c->chan.bcg = bcg;
- start_channel(c);
- return &c->chan;
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Implements input and output stream over TCP/IP transport.
+ */
+
+#if defined(_WRS_KERNEL)
+# include <vxWorks.h>
+#endif
+#include <stddef.h>
+#include <errno.h>
+#include <assert.h>
+#include "mdep.h"
+#include "tcf.h"
+#include "channel.h"
+#include "channel_tcp.h"
+#include "myalloc.h"
+#include "protocol.h"
+#include "events.h"
+#include "exceptions.h"
+#include "trace.h"
+#include "json.h"
+#include "peer.h"
+#include "ip_ifc.h"
+
+#define ESC 3
+#define BUF_SIZE 0x1000
+#define CHANNEL_MAGIC 0x87208956
+#define REFRESH_TIME 15
+#define STALE_TIME_DELTA (REFRESH_TIME * 2)
+#define MAX_IFC 10
+
+#define is_suspended(CH) ((CH)->chan.spg && (CH)->chan.spg->suspended)
+
+typedef struct ChannelTCP ChannelTCP;
+
+struct ChannelTCP {
+ Channel chan; /* Public channel information - must be first */
+ int magic; /* Magic number */
+ int socket; /* Socket file descriptor */
+ pthread_t thread; /* Socket receiving thread */
+ int thread_exited;
+ pthread_mutex_t mutex; /* Channel data access synchronization lock */
+ pthread_cond_t signal;
+ int long_msg; /* Message is longer then buffer, handlig should start before receiving EOM */
+ int waiting_space; /* Receiving thread is waiting for buffer space */
+ int waiting_data; /* Dispatch thread is waiting for data to read (long messages only) */
+ int message_count; /* Number of messages waiting to be dispatched */
+ int event_posted; /* Message handling event is posted to event queue */
+ int lock_cnt; /* Stream lock count, when > 0 channel cannot be deleted */
+ int handling_msg; /* Stream mutex is locked for input message handling */
+
+ /* Input stream buffer */
+ unsigned char ibuf[BUF_SIZE];
+ int ibuf_inp;
+ int ibuf_out;
+ int eof;
+ int peek;
+
+ /* Output stream state */
+ char obuf[BUF_SIZE];
+ int obuf_inp;
+ int out_errno;
+};
+
+typedef struct ServerTCP ServerTCP;
+
+struct ServerTCP {
+ ChannelServer serv;
+ int sock;
+ TCFSuspendGroup * spg;
+ TCFBroadcastGroup * bcg;
+ pthread_t server_thread;
+ PeerServer * ps;
+ LINK servlink;
+};
+
+#define channel2tcp(A) ((ChannelTCP *)((char *)(A) - offsetof(ChannelTCP, chan)))
+#define inp2channel(A) ((Channel *)((char *)(A) - offsetof(Channel, inp)))
+#define out2channel(A) ((Channel *)((char *)(A) - offsetof(Channel, out)))
+#define server2tcp(A) ((ServerTCP *)((char *)(A) - offsetof(ServerTCP, serv)))
+#define servlink2tcp(A) ((ServerTCP *)((char *)(A) - offsetof(ServerTCP, servlink)))
+
+static ChannelCloseListener close_listeners[16];
+static int close_listeners_cnt = 0;
+static LINK server_list;
+
+static void delete_channel(ChannelTCP * c) {
+ int i;
+ trace(LOG_PROTOCOL, "Deleting channel 0x%08x", c);
+ assert(c->lock_cnt == 0);
+ assert(c->magic == CHANNEL_MAGIC);
+ c->chan.cb->disconnected(&c->chan);
+ for (i = 0; i < close_listeners_cnt; i++) {
+ close_listeners[i](&c->chan);
+ }
+ if (c->chan.bcg) list_remove(&c->chan.bclink);
+ if (c->chan.spg) list_remove(&c->chan.susplink);
+ c->magic = 0;
+ loc_free(c);
+}
+
+static void tcp_lock(Channel * c) {
+ ChannelTCP * channel = channel2tcp(c);
+ assert(is_dispatch_thread());
+ assert(channel->magic == CHANNEL_MAGIC);
+ channel->lock_cnt++;
+}
+
+static void tcp_unlock(Channel * c) {
+ ChannelTCP * channel = channel2tcp(c);
+ assert(is_dispatch_thread());
+ assert(channel->magic == CHANNEL_MAGIC);
+ assert(channel->lock_cnt > 0);
+ channel->lock_cnt--;
+ if (channel->lock_cnt == 0) delete_channel(channel);
+}
+
+static int tcp_is_closed(Channel * c) {
+ ChannelTCP * channel = channel2tcp(c);
+ assert(is_dispatch_thread());
+ assert(channel->magic == CHANNEL_MAGIC);
+ assert(channel->lock_cnt > 0);
+ return channel->socket < 0;
+}
+
+static void flush_stream(OutputStream * out) {
+ int cnt = 0;
+ ChannelTCP * channel = channel2tcp(out2channel(out));
+ assert(is_dispatch_thread());
+ assert(channel->magic == CHANNEL_MAGIC);
+ if (channel->obuf_inp == 0) return;
+ if (channel->socket < 0) return;
+ if (channel->out_errno) return;
+ while (cnt < channel->obuf_inp) {
+ int wr = send(channel->socket, channel->obuf + cnt, channel->obuf_inp - cnt, 0);
+ if (wr < 0) {
+ int err = errno;
+ trace(LOG_PROTOCOL, "Can't sent() on channel 0x%08x: %d %s", channel, err, errno_to_str(err));
+ channel->out_errno = err;
+ return;
+ }
+ cnt += wr;
+ }
+ assert(cnt == channel->obuf_inp);
+ channel->obuf_inp = 0;
+}
+
+static void write_stream(OutputStream * out, int byte) {
+ ChannelTCP * channel = channel2tcp(out2channel(out));
+ int b0 = byte;
+ assert(is_dispatch_thread());
+ assert(channel->magic == CHANNEL_MAGIC);
+ if (channel->socket < 0) return;
+ if (channel->out_errno) return;
+ if (b0 < 0) byte = ESC;
+ channel->obuf[channel->obuf_inp++] = byte;
+ if (channel->obuf_inp == BUF_SIZE) flush_stream(out);
+ if (b0 < 0 || b0 == ESC) {
+ if (b0 == ESC) byte = 0;
+ else if (b0 == MARKER_EOM) byte = 1;
+ else if (b0 == MARKER_EOS) byte = 2;
+ else assert(0);
+ if (channel->socket < 0) return;
+ if (channel->out_errno) return;
+ channel->obuf[channel->obuf_inp++] = byte;
+ if (channel->obuf_inp == BUF_SIZE) flush_stream(out);
+ }
+}
+
+static int read_byte(ChannelTCP * channel) {
+ int res;
+ assert(channel->message_count > 0);
+ while (channel->ibuf_inp == channel->ibuf_out) {
+ assert(channel->long_msg);
+ assert(channel->message_count == 1);
+ if (channel->waiting_space) {
+ assert(!channel->waiting_data);
+ pthread_cond_signal(&channel->signal);
+ channel->waiting_space = 0;
+ }
+ if (channel->eof) return MARKER_EOS;
+ if (channel->socket < 0) return MARKER_EOS;
+ assert(!channel->waiting_data);
+ assert(!channel->waiting_space);
+ channel->waiting_data = 1;
+ pthread_cond_wait(&channel->signal, &channel->mutex);
+ assert(!channel->waiting_data);
+ }
+ res = channel->ibuf[channel->ibuf_out];
+ channel->ibuf_out = (channel->ibuf_out + 1) % BUF_SIZE;
+ return res;
+}
+
+static int read_stream(InputStream * inp) {
+ int b;
+ ChannelTCP * c = channel2tcp(inp2channel(inp));
+
+ assert(is_dispatch_thread());
+ assert(c->magic == CHANNEL_MAGIC);
+
+ if (c->peek != MARKER_NULL) {
+ assert(c->peek != MARKER_EOM);
+ b = c->peek;
+ c->peek = MARKER_NULL;
+ }
+ else {
+ if (!c->handling_msg) {
+ pthread_mutex_lock(&c->mutex);
+ c->handling_msg = 1;
+ }
+ b = read_byte(c);
+ if (b == ESC) {
+ b = read_byte(c);
+ if (b == 0) {
+ b = ESC;
+ }
+ else if (b == 1) {
+ b = MARKER_EOM;
+ c->message_count--;
+ if (c->waiting_space) {
+ assert(!c->waiting_data);
+ pthread_cond_signal(&c->signal);
+ c->waiting_space = 0;
+ }
+ pthread_mutex_unlock(&c->mutex);
+ c->handling_msg = 0;
+ }
+ else if (b == 2) {
+ b = MARKER_EOS;
+ }
+ }
+ }
+
+ return b;
+}
+
+static int peek_stream(InputStream * inp) {
+ ChannelTCP * c = channel2tcp(inp2channel(inp));
+ return c->peek = read_stream(inp);
+}
+
+static void send_eof_and_close(Channel * channel, int err) {
+ ChannelTCP * c = channel2tcp(channel);
+ assert(c->magic == CHANNEL_MAGIC);
+ write_stream(&c->chan.out, MARKER_EOS);
+ write_errno(&c->chan.out, err);
+ c->chan.out.write(&c->chan.out, MARKER_EOM);
+ c->chan.out.flush(&c->chan.out);
+ trace(LOG_PROTOCOL, "Closing socket, channel 0x%08x", c);
+ closesocket(c->socket);
+ c->socket = -1;
+}
+
+static void handle_channel_msg(void * x) {
+ Trap trap;
+ ChannelTCP * c = (ChannelTCP *)x;
+ assert(is_dispatch_thread());
+ for (;;) {
+ assert(c->magic == CHANNEL_MAGIC);
+ if (!c->handling_msg) {
+ pthread_mutex_lock(&c->mutex);
+ c->handling_msg = 1;
+ }
+ assert(c->event_posted);
+ if (c->thread_exited && (c->socket < 0 || c->message_count == 0 || c->long_msg)) {
+ void * res = NULL;
+ c->event_posted = 0;
+ c->handling_msg = 0;
+ pthread_mutex_unlock(&c->mutex);
+ if (c->thread) pthread_join(c->thread, &res);
+ if (c->socket >= 0) send_eof_and_close(&c->chan, 0);
+ tcp_unlock(&c->chan);
+ return;
+ }
+ if (c->message_count == 0 || is_suspended(c)) {
+ c->event_posted = 0;
+ c->handling_msg = 0;
+ pthread_mutex_unlock(&c->mutex);
+ break;
+ }
+ if (set_trap(&trap)) {
+ c->chan.cb->receive(&c->chan);
+ clear_trap(&trap);
+ }
+ else {
+ trace(LOG_ALWAYS, "Exception handling protocol message: %d %s",
+ trap.error, errno_to_str(trap.error));
+ c->peek = MARKER_NULL;
+ c->ibuf_out = c->ibuf_inp;
+ c->message_count = 0;
+ send_eof_and_close(&c->chan, trap.error);
+ }
+ }
+ if (c->chan.bcg) {
+ c->chan.bcg->out.flush(&c->chan.bcg->out);
+ }
+ else {
+ c->chan.out.flush(&c->chan.out);
+ }
+}
+
+static void channel_check_pending(Channel * c) {
+ ChannelTCP * channel = channel2tcp(c);
+ assert(is_dispatch_thread());
+ if (!is_suspended(channel)) {
+ pthread_mutex_lock(&channel->mutex);
+ if (channel->message_count > 0 && !channel->event_posted) {
+ post_event(handle_channel_msg, channel);
+ channel->event_posted = 1;
+ }
+ pthread_mutex_unlock(&channel->mutex);
+ }
+}
+
+static int channel_get_message_count(Channel * c) {
+ ChannelTCP * channel = channel2tcp(c);
+ int cnt;
+ assert(is_dispatch_thread());
+ pthread_mutex_lock(&channel->mutex);
+ cnt = channel->message_count;
+ pthread_mutex_unlock(&channel->mutex);
+ return cnt;
+}
+
+static void * stream_socket_handler(void * x) {
+ int i;
+ int esc = 0;
+ ChannelTCP * channel = (ChannelTCP *)x;
+ unsigned char pkt[BUF_SIZE];
+
+ pthread_mutex_lock(&channel->mutex);
+ while (!channel->eof && channel->socket >= 0) {
+ int err = 0;
+ int rd = 0;
+
+ pthread_mutex_unlock(&channel->mutex);
+ rd = recv(channel->socket, (void *)pkt, sizeof(pkt), 0);
+ err = errno;
+ assert(channel->magic == CHANNEL_MAGIC);
+ pthread_mutex_lock(&channel->mutex);
+
+ if (rd < 0) {
+ trace(LOG_ALWAYS, "Can't read from socket: %s", errno_to_str(errno));
+ if (channel->socket < 0) break;
+ channel->eof = 1;
+ break;
+ }
+
+ if (rd == 0) {
+ trace(LOG_PROTOCOL, "Socket is shutdown by remote peer, channel 0x%08x", channel);
+ channel->eof = 1;
+ break;
+ }
+
+ for (i = 0; i < rd && !channel->eof; i++) {
+ unsigned char ch = pkt[i];
+ int ibuf_next = (channel->ibuf_inp + 1) % BUF_SIZE;
+ while (ibuf_next == channel->ibuf_out) {
+ if (channel->message_count == 0 && !channel->long_msg) {
+ channel->long_msg = 1;
+ channel->message_count = 1;
+ if (!is_suspended(channel) && !channel->event_posted) {
+ post_event(handle_channel_msg, channel);
+ channel->event_posted = 1;
+ }
+ }
+ assert(channel->message_count > 0);
+ assert(!channel->waiting_data);
+ assert(!channel->waiting_space);
+ channel->waiting_space = 1;
+ pthread_cond_wait(&channel->signal, &channel->mutex);
+ assert(ibuf_next == (channel->ibuf_inp + 1) % BUF_SIZE);
+ assert(!channel->waiting_space);
+ }
+ if (esc) {
+ esc = 0;
+ switch (ch) {
+ case 0:
+ /* ESC byte */
+ break;
+ case 1:
+ /* EOM - End Of Message */
+ if (channel->long_msg) {
+ channel->long_msg = 0;
+ assert(channel->message_count == 1);
+ }
+ else {
+ channel->message_count++;
+ if (!is_suspended(channel) && !channel->event_posted) {
+ post_event(handle_channel_msg, channel);
+ channel->event_posted = 1;
+ }
+ }
+ break;
+ case 2:
+ /* EOS - End Of Stream */
+ trace(LOG_PROTOCOL, "End of stream on channel 0x%08x", channel);
+ channel->eof = 1;
+ break;
+ default:
+ /* Invalid escape sequence */
+ trace(LOG_ALWAYS, "Protocol: Invalid escape sequence");
+ channel->eof = 1;
+ ch = 2;
+ break;
+ }
+ }
+ else {
+ esc = ch == ESC;
+ }
+ channel->ibuf[channel->ibuf_inp] = ch;
+ channel->ibuf_inp = ibuf_next;
+ if (channel->waiting_data) {
+ assert(!channel->waiting_space);
+ pthread_cond_signal(&channel->signal);
+ channel->waiting_data = 0;
+ }
+ }
+ }
+ if (channel->waiting_data) {
+ assert(!channel->waiting_space);
+ pthread_cond_signal(&channel->signal);
+ channel->waiting_data = 0;
+ }
+ if (!channel->event_posted) {
+ post_event(handle_channel_msg, channel);
+ channel->event_posted = 1;
+ }
+ channel->thread_exited = 1;
+ pthread_mutex_unlock(&channel->mutex);
+ return NULL;
+}
+
+static ChannelTCP * create_channel(int sock) {
+ const int i = 1;
+ ChannelTCP * c;
+
+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&i, sizeof(i)) < 0) {
+ trace(LOG_ALWAYS, "Can't set TCP_NODELAY option on a socket: %s", errno_to_str(errno));
+ closesocket(sock);
+ return NULL;
+ }
+
+ c = loc_alloc_zero(sizeof *c);
+ c->magic = CHANNEL_MAGIC;
+ pthread_mutex_init(&c->mutex, NULL);
+ pthread_cond_init(&c->signal, NULL);
+ c->chan.inp.read = read_stream;
+ c->chan.inp.peek = peek_stream;
+ c->chan.out.write = write_stream;
+ c->chan.out.flush = flush_stream;
+ c->chan.check_pending = channel_check_pending;
+ c->chan.message_count = channel_get_message_count;
+ c->chan.lock = tcp_lock;
+ c->chan.unlock = tcp_unlock;
+ c->chan.is_closed = tcp_is_closed;
+ c->chan.close = send_eof_and_close;
+ c->socket = sock;
+ c->peek = MARKER_NULL;
+ return c;
+}
+
+static void start_channel(ChannelTCP * c) {
+ int error;
+
+ if (c->chan.spg) list_add_last(&c->chan.susplink, &c->chan.spg->channels);
+ if (c->chan.bcg) list_add_last(&c->chan.bclink, &c->chan.bcg->channels);
+
+ tcp_lock(&c->chan);
+ trace(LOG_PROTOCOL, "Starting channel 0x%08x", c);
+
+ c->chan.cb->connecting(&c->chan);
+
+ error = pthread_create(&c->thread, &pthread_create_attr, stream_socket_handler, c);
+ if (error) {
+ trace(LOG_ALWAYS, "Can't create a thread: %d %s", error, errno_to_str(error));
+ send_eof_and_close(&c->chan, 0);
+ tcp_unlock(&c->chan);
+ }
+}
+
+static void refresh_peer_server(int sock, PeerServer * ps) {
+ int i;
+ PeerServer * ps2;
+ struct sockaddr_in sin;
+#if defined(_WRS_KERNEL)
+ int sinlen;
+#else
+ socklen_t sinlen;
+#endif
+ char *transport;
+ char *str_host;
+ char str_port[32];
+ char str_id[64];
+ int ifcind;
+ struct in_addr src_addr;
+ ip_ifc_info ifclist[MAX_IFC];
+
+ sinlen = sizeof sin;
+ if (getsockname(sock, (struct sockaddr *)&sin, &sinlen) != 0) {
+ trace(LOG_ALWAYS, "refresh_peer_server: getsockname error: %s", errno_to_str(errno));
+ return;
+ }
+ ifcind = build_ifclist(sock, MAX_IFC, ifclist);
+ while (ifcind-- > 0) {
+ if (sin.sin_addr.s_addr != INADDR_ANY &&
+ (ifclist[ifcind].addr & ifclist[ifcind].mask) !=
+ (sin.sin_addr.s_addr & ifclist[ifcind].mask)) {
+ continue;
+ }
+ src_addr.s_addr = ifclist[ifcind].addr;
+ ps2 = peer_server_alloc();
+ ps2->flags = ps->flags | PS_FLAG_LOCAL | PS_FLAG_DISCOVERABLE;
+ for (i = 0; i < ps->ind; i++) {
+ peer_server_addprop(ps2, loc_strdup(ps->list[i].name), loc_strdup(ps->list[i].value));
+ }
+ transport = peer_server_getprop(ps2, "TransportName", NULL);
+ assert(transport != NULL);
+ snprintf(str_port, sizeof(str_port), "%d", ntohs(sin.sin_port));
+ str_host = loc_strdup(inet_ntoa(src_addr));
+ snprintf(str_id, sizeof(str_id), "%s:%s:%s", transport, str_host, str_port);
+ peer_server_addprop(ps2, loc_strdup("ID"), loc_strdup(str_id));
+ peer_server_addprop(ps2, loc_strdup("Host"), str_host);
+ peer_server_addprop(ps2, loc_strdup("Port"), loc_strdup(str_port));
+ peer_server_add(ps2, STALE_TIME_DELTA);
+ }
+}
+
+static void refresh_all_peer_server(void *x) {
+ LINK * l;
+
+ if (list_is_empty(&server_list)) {
+ return;
+ }
+ l = server_list.next;
+ while (l != &server_list) {
+ ServerTCP * si = servlink2tcp(l);
+ refresh_peer_server(si->sock, si->ps);
+ l = l->next;
+ }
+ post_event_with_delay(refresh_all_peer_server, NULL, REFRESH_TIME*1000*1000);
+}
+
+struct NewChannelInfo {
+ int sock;
+ ServerTCP * si;
+};
+
+static void handle_channel_open(void * x) {
+ struct NewChannelInfo * i = x;
+ ChannelTCP * c;
+
+ c = create_channel(i->sock);
+ i->si->serv.cb->newConnection(&i->si->serv, &c->chan);
+ start_channel(c);
+ loc_free(i);
+}
+
+static void * tcp_server_socket_handler(void * x) {
+ ServerTCP * si = x;
+
+ while (si->sock >= 0) {
+ struct NewChannelInfo *i;
+ int sock = accept(si->sock, NULL, NULL);
+ if (sock < 0) {
+ if (si->sock < 0) {
+ break;
+ }
+ trace(LOG_ALWAYS, "socket accept failed: %d %s", errno, errno_to_str(errno));
+ continue;
+ }
+ i = loc_alloc(sizeof *i);
+ i->sock = sock;
+ i->si = si;
+ post_event(handle_channel_open, i);
+ }
+ loc_free(si);
+ return 0;
+}
+
+static void server_close(ChannelServer * serv) {
+ ServerTCP * s = server2tcp(serv);
+
+ assert(is_dispatch_thread());
+ if (s->sock < 0) {
+ return;
+ }
+ list_remove(&s->servlink);
+ peer_server_free(s->ps);
+ closesocket(s->sock);
+ s->sock = -1;
+}
+
+ChannelServer * channel_tcp_server(PeerServer * ps, ChannelServerCallbacks * cb, void * client_data) {
+ const int i = 1;
+ int sock;
+ int error;
+ char * reason = NULL;
+ struct addrinfo hints;
+ struct addrinfo * reslist = NULL;
+ struct addrinfo * res = NULL;
+ ServerTCP * si;
+ char * host = peer_server_getprop(ps, "Host", NULL);
+ char * port = peer_server_getprop(ps, "Port", "");
+
+ assert(is_dispatch_thread());
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_flags = AI_PASSIVE;
+ error = loc_getaddrinfo(host, port, &hints, &reslist);
+ if (error) {
+ trace(LOG_ALWAYS, "getaddrinfo error: %s", loc_gai_strerror(error));
+ return NULL;
+ }
+ sock = -1;
+ reason = NULL;
+ for (res = reslist; res != NULL; res = res->ai_next) {
+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sock < 0) {
+ error = errno;
+ reason = "create";
+ continue;
+ }
+ /* Allow rapid reuse of this port. */
+ if (((struct sockaddr_in *)res->ai_addr)->sin_port != 0 &&
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i)) < 0) {
+ error = errno;
+ reason = "setsockopt(reuse) for";
+ closesocket(sock);
+ sock = -1;
+ continue;
+ }
+ if (bind(sock, res->ai_addr, res->ai_addrlen)) {
+ error = errno;
+ reason = "bind";
+ closesocket(sock);
+ sock = -1;
+ continue;
+ }
+ if (listen(sock, 16)) {
+ error = errno;
+ reason = "listen on";
+ closesocket(sock);
+ sock = -1;
+ continue;
+ }
+
+ /* Only create one listener - don't see how getaddrinfo with
+ * the given arguments could return more then one anyway */
+ break;
+ }
+ loc_freeaddrinfo(reslist);
+ if (sock < 0) {
+ trace(LOG_ALWAYS, "socket %s error: %s", reason, errno_to_str(error));
+ return NULL;
+ }
+ si = loc_alloc(sizeof *si);
+ si->serv.client_data = client_data;
+ si->serv.cb = cb;
+ si->serv.close = server_close;
+ si->sock = sock;
+ si->ps = ps;
+ if (server_list.next == NULL) list_init(&server_list);
+ if (list_is_empty(&server_list)) {
+ post_event_with_delay(refresh_all_peer_server, NULL, REFRESH_TIME * 1000 * 1000);
+ }
+ list_add_last(&si->servlink, &server_list);
+ refresh_peer_server(sock, ps);
+ if (pthread_create(&si->server_thread, &pthread_create_attr, tcp_server_socket_handler, si) != 0) {
+ perror("Can't create socket listener thread");
+ return NULL;
+ }
+ return &si->serv;
+}
+
+Channel * channel_tcp_connect(PeerServer * ps, ChannelCallbacks * cb,
+ void * client_data, TCFSuspendGroup * spg, TCFBroadcastGroup * bcg) {
+ const int i = 1;
+ int sock = -1;
+ ChannelTCP * c = NULL;
+ int error = 0;
+ char * reason = NULL;
+ char * host = peer_server_getprop(ps, "Host", NULL);
+ char * port = peer_server_getprop(ps, "Port", NULL);
+ struct addrinfo hints;
+ struct addrinfo * reslist = NULL;
+ struct addrinfo * res = NULL;
+
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ error = loc_getaddrinfo(host, port, &hints, &reslist);
+ if (error) {
+ trace(LOG_ALWAYS, "getaddrinfo error: %s", loc_gai_strerror(error));
+ return NULL;
+ }
+ sock = -1;
+ reason = NULL;
+ for (res = reslist; res != NULL; res = res->ai_next) {
+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sock < 0) {
+ error = errno;
+ reason = "create";
+ continue;
+ }
+ if (connect(sock, res->ai_addr, res->ai_addrlen)) {
+ error = errno;
+ reason = "connect";
+ closesocket(sock);
+ sock = -1;
+ continue;
+ }
+ break;
+ }
+ loc_freeaddrinfo(reslist);
+ if (sock < 0) {
+ trace(LOG_ALWAYS, "socket %s error: %s", reason, errno_to_str(error));
+ return NULL;
+ }
+
+ c = create_channel(sock);
+ if (c == NULL) {
+ return NULL;
+ }
+ c->chan.cb = cb;
+ c->chan.client_data = client_data;
+ c->chan.spg = spg;
+ c->chan.bcg = bcg;
+ start_channel(c);
+ return &c->chan;
+}
diff --git a/channel_tcp.h b/channel_tcp.h
index fe135957..9b7cc4ee 100644
--- a/channel_tcp.h
+++ b/channel_tcp.h
@@ -1,31 +1,31 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Transport agnostic channel interface
- */
-
-#ifndef D_channel_tcp
-#define D_channel_tcp
-
-/*
- * Start TCP channel listener
- */
-extern ChannelServer * channel_tcp_server(PeerServer * ps,
- ChannelServerCallbacks * cb, void * client_data);
-
-/*
- * Connect client side over TCP
- */
-extern Channel * channel_tcp_connect(PeerServer * ps, ChannelCallbacks * cb,
- void *client_data, TCFSuspendGroup *, TCFBroadcastGroup *);
-
-#endif
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Transport agnostic channel interface
+ */
+
+#ifndef D_channel_tcp
+#define D_channel_tcp
+
+/*
+ * Start TCP channel listener
+ */
+extern ChannelServer * channel_tcp_server(PeerServer * ps,
+ ChannelServerCallbacks * cb, void * client_data);
+
+/*
+ * Connect client side over TCP
+ */
+extern Channel * channel_tcp_connect(PeerServer * ps, ChannelCallbacks * cb,
+ void *client_data, TCFSuspendGroup *, TCFBroadcastGroup *);
+
+#endif
diff --git a/cmdline.c b/cmdline.c
index 3b0836af..f95ccfc1 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/cmdline.h b/cmdline.h
index e5d5cde2..1e2898cf 100644
--- a/cmdline.h
+++ b/cmdline.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/config.h b/config.h
index 63e5334b..d386c7aa 100644
--- a/config.h
+++ b/config.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/context.c b/context.c
index 32b1e3a7..0d34542d 100644
--- a/context.c
+++ b/context.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/context.h b/context.h
index 0dbc0712..ac3d8a1f 100644
--- a/context.h
+++ b/context.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/diagnostics.c b/diagnostics.c
index e949f668..1cacdb81 100644
--- a/diagnostics.c
+++ b/diagnostics.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/diagnostics.h b/diagnostics.h
index d5f89880..8e396fe6 100644
--- a/diagnostics.h
+++ b/diagnostics.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/discovery.c b/discovery.c
index b07880b3..e45aa7e6 100644
--- a/discovery.c
+++ b/discovery.c
@@ -1,263 +1,263 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Implements discovery.
- */
-
-#if defined(_WRS_KERNEL)
-# include <vxWorks.h>
-#endif
-#include <stddef.h>
-#include <errno.h>
-#include <assert.h>
-#include "mdep.h"
-#include "tcf.h"
-#include "discovery.h"
-#include "discovery_udp.h"
-#include "protocol.h"
-#include "channel.h"
-#include "myalloc.h"
-#include "events.h"
-#include "trace.h"
-#include "exceptions.h"
-#include "json.h"
-#include "peer.h"
-
-static const char * LOCATOR = "Locator";
-
-#define REFRESH_TIME 10
-#define STALE_TIME_DELTA (REFRESH_TIME*3)
-
-static int chan_max;
-static int chan_ind;
-static Channel ** chan_list;
-static Channel * client_chan;
-static int discovery_ismaster;
-static DiscoveryMasterNotificationCB master_notifier;
-static void restart_discovery(void *);
-
-static void generate_peer_info(PeerServer * ps, OutputStream * out) {
- int i;
-
- out->write(out, '{');
- json_write_string(out, "ID");
- out->write(out, ':');
- json_write_string(out, ps->id);
- for (i = 0; i < ps->ind; i++) {
- out->write(out, ',');
- json_write_string(out, ps->list[i].name);
- out->write(out, ':');
- json_write_string(out, ps->list[i].value);
- }
- out->write(out, '}');
-}
-
-static void remote_peer_change(PeerServer * ps, int changeType, OutputStream * out) {
- if ((ps->flags & PS_FLAG_DISCOVERABLE) == 0) return;
- trace(LOG_DISCOVERY, "discovery: remote_peer_change, id %s, type %d", ps->id, changeType);
- write_stringz(out, "E");
- write_stringz(out, LOCATOR);
- if (changeType >= 0) {
- if (changeType > 0) {
- write_stringz(out, "peerAdded");
- }
- else {
- write_stringz(out, "peerChanged");
- }
- generate_peer_info(ps, out);
- }
- else {
- write_stringz(out, "peerRemoved");
- json_write_string(out, ps->id);
- }
- out->write(out, 0);
- out->write(out, MARKER_EOM);
- out->flush(out);
-}
-
-static int generate_peer_added_event(PeerServer * ps, void * x) {
- OutputStream * out = x;
-
- remote_peer_change(ps, 1, out);
- return 0;
-}
-
-static void publish_peer_reply(Channel * c, void * client_data, int error) {
- unsigned long refresh_time;
- char msg[256];
-
- trace(LOG_DISCOVERY, "discovery: publish peer reply");
- if (error) {
- trace(LOG_DISCOVERY, " error %d", error);
- return;
- }
- error = json_read_long(&c->inp);
- if (c->inp.read(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
- json_read_string(&c->inp, msg, sizeof msg);
- if (c->inp.read(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
- refresh_time = json_read_ulong(&c->inp);
- if (c->inp.read(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
- trace(LOG_DISCOVERY, " refresh_time %d", refresh_time);
- if (c->inp.read(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
-}
-
-static void generate_publish_peer_command(Channel * c, PeerServer *ps) {
- if ((ps->flags & (PS_FLAG_LOCAL | PS_FLAG_PRIVATE | PS_FLAG_DISCOVERABLE)) !=
- (PS_FLAG_LOCAL | PS_FLAG_DISCOVERABLE)) {
- return;
- }
- trace(LOG_DISCOVERY, "discovery: publish peer command, id %s", ps->id);
- protocol_send_command(c->client_data, c, LOCATOR, "publishPeer", publish_peer_reply, NULL);
- generate_peer_info(ps, &c->out);
- c->out.write(&c->out, 0);
- c->out.write(&c->out, MARKER_EOM);
- c->out.flush(&c->out);
-}
-
-/*
- * Add channel to include in discovery updates
- */
-void discovery_channel_add(Channel * c) {
- if (chan_ind == chan_max) {
- if (chan_list == NULL) {
- chan_max = 1;
- chan_list = loc_alloc(chan_max * sizeof *chan_list);
- }
- else {
- chan_max *= 2;
- chan_list = loc_realloc(chan_list, chan_max * sizeof *chan_list);
- }
- chan_list[chan_ind++] = c;
- }
- peer_server_iter(generate_peer_added_event, &c->out);
-}
-
-/*
- * Remove channel from discovery updates
- */
-void discovery_channel_remove(Channel * c) {
- int i;
-
- for (i = 0; i < chan_ind; i++) {
- if (chan_list[i] == c) break;
- }
- chan_ind--;
- for (; i < chan_ind; i++) {
- chan_list[i] = chan_list[i+1];
- }
-}
-
-static void channel_client_connecting(Channel * c) {
- trace(LOG_DISCOVERY, "discovery: channel_client_connecting");
-
- send_hello_message(c->client_data, c);
- discovery_channel_add(c);
- c->out.flush(&c->out);
-}
-
-static void channel_client_connected(Channel * c) {
- int i;
-
- trace(LOG_DISCOVERY, "discovery: channel_client_connected, peer services:");
- for (i = 0; i < c->peer_service_cnt; i++) {
- trace(LOG_DISCOVERY, " %s", c->peer_service_list[i]);
- }
-}
-
-static void channel_client_receive(Channel * c) {
- handle_protocol_message(c->client_data, c);
-}
-
-static void channel_client_disconnected(Channel * c) {
- trace(LOG_DISCOVERY, "discovery: channel_client_disconnected");
- discovery_channel_remove(c);
- protocol_channel_closed(c->client_data, c);
- protocol_free(c->client_data);
- post_event_with_delay(restart_discovery, NULL, 300*1000);
-}
-
-static ChannelCallbacks clientccb = {
- channel_client_connecting,
- channel_client_connected,
- channel_client_receive,
- channel_client_disconnected
-};
-
-static void peer_list_changed(PeerServer * ps, int changeType, void * client_data) {
- int i;
-
- if (client_chan != NULL && changeType > 0) {
- generate_publish_peer_command(client_chan, ps);
- }
- for (i = 0; i < chan_ind; i++) {
- remote_peer_change(ps, changeType, &chan_list[i]->out);
- }
-}
-
-/*
- * Make local peers discoverable
- */
-static void make_local_discoverable(void) {
- peer_server_add_listener(peer_list_changed, NULL);
-}
-
-/*
- * Connect discovery client
- */
-Channel * discovery_client(void) {
- Protocol * proto;
- Channel * c;
- PeerServer * ps = channel_peer_from_url(DEFAULT_DISCOVERY_URL);
-
- proto = protocol_alloc();
- c = channel_connect(ps, &clientccb, proto, NULL, NULL);
- peer_server_free(ps);
- if (c == NULL) {
- trace(LOG_DISCOVERY, "cannot connect to TCF discovery");
- protocol_free(proto);
- return NULL;
- }
- protocol_channel_opened(proto, c);
- add_event_handler(c, LOCATOR, "peerAdded", event_locator_peer_added);
- add_event_handler(c, LOCATOR, "peerChanged", event_locator_peer_changed);
- add_event_handler(c, LOCATOR, "peerRemoved", event_locator_peer_removed);
- return c;
-}
-
-static int start_discovery(void) {
- assert(is_dispatch_thread());
- assert(!discovery_ismaster);
- trace(LOG_DISCOVERY, "discovery start");
- if (discovery_udp_server(NULL) == 0) {
- discovery_ismaster = 1;
- }
- else {
- client_chan = discovery_client();
- if (client_chan == NULL) {
- post_event_with_delay(restart_discovery, NULL, 300*1000);
- }
- }
- return discovery_ismaster;
-}
-
-static void restart_discovery(void * x) {
- if (start_discovery()) {
- master_notifier();
- }
-}
-
-int discovery_start(DiscoveryMasterNotificationCB mastercb) {
- assert(mastercb != NULL);
- master_notifier = mastercb;
- make_local_discoverable();
- return start_discovery();
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Implements discovery.
+ */
+
+#if defined(_WRS_KERNEL)
+# include <vxWorks.h>
+#endif
+#include <stddef.h>
+#include <errno.h>
+#include <assert.h>
+#include "mdep.h"
+#include "tcf.h"
+#include "discovery.h"
+#include "discovery_udp.h"
+#include "protocol.h"
+#include "channel.h"
+#include "myalloc.h"
+#include "events.h"
+#include "trace.h"
+#include "exceptions.h"
+#include "json.h"
+#include "peer.h"
+
+static const char * LOCATOR = "Locator";
+
+#define REFRESH_TIME 10
+#define STALE_TIME_DELTA (REFRESH_TIME*3)
+
+static int chan_max;
+static int chan_ind;
+static Channel ** chan_list;
+static Channel * client_chan;
+static int discovery_ismaster;
+static DiscoveryMasterNotificationCB master_notifier;
+static void restart_discovery(void *);
+
+static void generate_peer_info(PeerServer * ps, OutputStream * out) {
+ int i;
+
+ out->write(out, '{');
+ json_write_string(out, "ID");
+ out->write(out, ':');
+ json_write_string(out, ps->id);
+ for (i = 0; i < ps->ind; i++) {
+ out->write(out, ',');
+ json_write_string(out, ps->list[i].name);
+ out->write(out, ':');
+ json_write_string(out, ps->list[i].value);
+ }
+ out->write(out, '}');
+}
+
+static void remote_peer_change(PeerServer * ps, int changeType, OutputStream * out) {
+ if ((ps->flags & PS_FLAG_DISCOVERABLE) == 0) return;
+ trace(LOG_DISCOVERY, "discovery: remote_peer_change, id %s, type %d", ps->id, changeType);
+ write_stringz(out, "E");
+ write_stringz(out, LOCATOR);
+ if (changeType >= 0) {
+ if (changeType > 0) {
+ write_stringz(out, "peerAdded");
+ }
+ else {
+ write_stringz(out, "peerChanged");
+ }
+ generate_peer_info(ps, out);
+ }
+ else {
+ write_stringz(out, "peerRemoved");
+ json_write_string(out, ps->id);
+ }
+ out->write(out, 0);
+ out->write(out, MARKER_EOM);
+ out->flush(out);
+}
+
+static int generate_peer_added_event(PeerServer * ps, void * x) {
+ OutputStream * out = x;
+
+ remote_peer_change(ps, 1, out);
+ return 0;
+}
+
+static void publish_peer_reply(Channel * c, void * client_data, int error) {
+ unsigned long refresh_time;
+ char msg[256];
+
+ trace(LOG_DISCOVERY, "discovery: publish peer reply");
+ if (error) {
+ trace(LOG_DISCOVERY, " error %d", error);
+ return;
+ }
+ error = json_read_long(&c->inp);
+ if (c->inp.read(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
+ json_read_string(&c->inp, msg, sizeof msg);
+ if (c->inp.read(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
+ refresh_time = json_read_ulong(&c->inp);
+ if (c->inp.read(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
+ trace(LOG_DISCOVERY, " refresh_time %d", refresh_time);
+ if (c->inp.read(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
+}
+
+static void generate_publish_peer_command(Channel * c, PeerServer *ps) {
+ if ((ps->flags & (PS_FLAG_LOCAL | PS_FLAG_PRIVATE | PS_FLAG_DISCOVERABLE)) !=
+ (PS_FLAG_LOCAL | PS_FLAG_DISCOVERABLE)) {
+ return;
+ }
+ trace(LOG_DISCOVERY, "discovery: publish peer command, id %s", ps->id);
+ protocol_send_command(c->client_data, c, LOCATOR, "publishPeer", publish_peer_reply, NULL);
+ generate_peer_info(ps, &c->out);
+ c->out.write(&c->out, 0);
+ c->out.write(&c->out, MARKER_EOM);
+ c->out.flush(&c->out);
+}
+
+/*
+ * Add channel to include in discovery updates
+ */
+void discovery_channel_add(Channel * c) {
+ if (chan_ind == chan_max) {
+ if (chan_list == NULL) {
+ chan_max = 1;
+ chan_list = loc_alloc(chan_max * sizeof *chan_list);
+ }
+ else {
+ chan_max *= 2;
+ chan_list = loc_realloc(chan_list, chan_max * sizeof *chan_list);
+ }
+ chan_list[chan_ind++] = c;
+ }
+ peer_server_iter(generate_peer_added_event, &c->out);
+}
+
+/*
+ * Remove channel from discovery updates
+ */
+void discovery_channel_remove(Channel * c) {
+ int i;
+
+ for (i = 0; i < chan_ind; i++) {
+ if (chan_list[i] == c) break;
+ }
+ chan_ind--;
+ for (; i < chan_ind; i++) {
+ chan_list[i] = chan_list[i+1];
+ }
+}
+
+static void channel_client_connecting(Channel * c) {
+ trace(LOG_DISCOVERY, "discovery: channel_client_connecting");
+
+ send_hello_message(c->client_data, c);
+ discovery_channel_add(c);
+ c->out.flush(&c->out);
+}
+
+static void channel_client_connected(Channel * c) {
+ int i;
+
+ trace(LOG_DISCOVERY, "discovery: channel_client_connected, peer services:");
+ for (i = 0; i < c->peer_service_cnt; i++) {
+ trace(LOG_DISCOVERY, " %s", c->peer_service_list[i]);
+ }
+}
+
+static void channel_client_receive(Channel * c) {
+ handle_protocol_message(c->client_data, c);
+}
+
+static void channel_client_disconnected(Channel * c) {
+ trace(LOG_DISCOVERY, "discovery: channel_client_disconnected");
+ discovery_channel_remove(c);
+ protocol_channel_closed(c->client_data, c);
+ protocol_free(c->client_data);
+ post_event_with_delay(restart_discovery, NULL, 300*1000);
+}
+
+static ChannelCallbacks clientccb = {
+ channel_client_connecting,
+ channel_client_connected,
+ channel_client_receive,
+ channel_client_disconnected
+};
+
+static void peer_list_changed(PeerServer * ps, int changeType, void * client_data) {
+ int i;
+
+ if (client_chan != NULL && changeType > 0) {
+ generate_publish_peer_command(client_chan, ps);
+ }
+ for (i = 0; i < chan_ind; i++) {
+ remote_peer_change(ps, changeType, &chan_list[i]->out);
+ }
+}
+
+/*
+ * Make local peers discoverable
+ */
+static void make_local_discoverable(void) {
+ peer_server_add_listener(peer_list_changed, NULL);
+}
+
+/*
+ * Connect discovery client
+ */
+Channel * discovery_client(void) {
+ Protocol * proto;
+ Channel * c;
+ PeerServer * ps = channel_peer_from_url(DEFAULT_DISCOVERY_URL);
+
+ proto = protocol_alloc();
+ c = channel_connect(ps, &clientccb, proto, NULL, NULL);
+ peer_server_free(ps);
+ if (c == NULL) {
+ trace(LOG_DISCOVERY, "cannot connect to TCF discovery");
+ protocol_free(proto);
+ return NULL;
+ }
+ protocol_channel_opened(proto, c);
+ add_event_handler(c, LOCATOR, "peerAdded", event_locator_peer_added);
+ add_event_handler(c, LOCATOR, "peerChanged", event_locator_peer_changed);
+ add_event_handler(c, LOCATOR, "peerRemoved", event_locator_peer_removed);
+ return c;
+}
+
+static int start_discovery(void) {
+ assert(is_dispatch_thread());
+ assert(!discovery_ismaster);
+ trace(LOG_DISCOVERY, "discovery start");
+ if (discovery_udp_server(NULL) == 0) {
+ discovery_ismaster = 1;
+ }
+ else {
+ client_chan = discovery_client();
+ if (client_chan == NULL) {
+ post_event_with_delay(restart_discovery, NULL, 300*1000);
+ }
+ }
+ return discovery_ismaster;
+}
+
+static void restart_discovery(void * x) {
+ if (start_discovery()) {
+ master_notifier();
+ }
+}
+
+int discovery_start(DiscoveryMasterNotificationCB mastercb) {
+ assert(mastercb != NULL);
+ master_notifier = mastercb;
+ make_local_discoverable();
+ return start_discovery();
+}
diff --git a/discovery.h b/discovery.h
index e5f1b5d7..5cce5d84 100644
--- a/discovery.h
+++ b/discovery.h
@@ -1,56 +1,56 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Discovery interface
- */
-
-#ifndef D_discovery
-#define D_discovery
-
-#include "protocol.h"
-#include "channel.h"
-#include "link.h"
-
-#define DEFAULT_DISCOVERY_URL "TCP::1534"
-#define DISCOVERY_TCF_PORT "1534"
-
-/*
- * Connect discovery client
- */
-extern Channel * discovery_client(void);
-
-/*
- * Add channel to include in discovery updates
- */
-extern void discovery_channel_add(Channel *);
-
-/*
- * Remove channel from discovery updates
- */
-extern void discovery_channel_remove(Channel *);
-
-/*
- * Start discovery of remote peers. If no other master exist on the
- * local machine, then this instance will become master, otherwise a
- * client will attempt to connect to the existing master. If the
- * existing master disappears, then a new attempt will be made to
- * become master or connect as a client.
- *
- * Returns true if this is instance is the discovery master.
- * Otherwise returns false and the callback is invoked if this
- * instance becomes the master at a later stage.
- */
-
-typedef void (*DiscoveryMasterNotificationCB)(void);
-extern int discovery_start(DiscoveryMasterNotificationCB);
-
-#endif
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Discovery interface
+ */
+
+#ifndef D_discovery
+#define D_discovery
+
+#include "protocol.h"
+#include "channel.h"
+#include "link.h"
+
+#define DEFAULT_DISCOVERY_URL "TCP::1534"
+#define DISCOVERY_TCF_PORT "1534"
+
+/*
+ * Connect discovery client
+ */
+extern Channel * discovery_client(void);
+
+/*
+ * Add channel to include in discovery updates
+ */
+extern void discovery_channel_add(Channel *);
+
+/*
+ * Remove channel from discovery updates
+ */
+extern void discovery_channel_remove(Channel *);
+
+/*
+ * Start discovery of remote peers. If no other master exist on the
+ * local machine, then this instance will become master, otherwise a
+ * client will attempt to connect to the existing master. If the
+ * existing master disappears, then a new attempt will be made to
+ * become master or connect as a client.
+ *
+ * Returns true if this is instance is the discovery master.
+ * Otherwise returns false and the callback is invoked if this
+ * instance becomes the master at a later stage.
+ */
+
+typedef void (*DiscoveryMasterNotificationCB)(void);
+extern int discovery_start(DiscoveryMasterNotificationCB);
+
+#endif
diff --git a/discovery_help.c b/discovery_help.c
index ac516e06..cb764b9b 100644
--- a/discovery_help.c
+++ b/discovery_help.c
@@ -1,106 +1,106 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Implements discovery.
- */
-
-#if _WRS_KERNEL
-# include <vxWorks.h>
-#endif
-#include <stddef.h>
-#include <errno.h>
-#include <assert.h>
-#include "mdep.h"
-#include "tcf.h"
-#include "discovery.h"
-#include "protocol.h"
-#include "channel.h"
-#include "myalloc.h"
-#include "events.h"
-#include "trace.h"
-#include "exceptions.h"
-#include "json.h"
-#include "peer.h"
-
-/*
- * Channel callback handlers
- */
-static void channel_server_connecting(Channel *c) {
- trace(LOG_DISCOVERY, "discovery_help: channel_server_connecting");
-
- send_hello_message(c->client_data, c);
- discovery_channel_add(c);
- c->out.flush(&c->out);
-}
-
-static void channel_server_connected(Channel *c) {
- int i;
-
- trace(LOG_DISCOVERY, "discovery_help: channel_server_connected, peer services:");
- for (i = 0; i < c->peer_service_cnt; i++) {
- trace(LOG_DISCOVERY, " %s", c->peer_service_list[i]);
- }
-}
-
-static void channel_server_receive(Channel *c) {
- handle_protocol_message(c->client_data, c);
-}
-
-static void channel_server_disconnected(Channel *c) {
- trace(LOG_DISCOVERY, "discovery_help: channel_server_disconnected\n");
- discovery_channel_remove(c);
- protocol_channel_closed(c->client_data, c);
-}
-
-static ChannelCallbacks serverccb = {
- channel_server_connecting,
- channel_server_connected,
- channel_server_receive,
- channel_server_disconnected
-};
-
-/*
- * New incomming connection
- */
-static void discovery_new_connection(ChannelServer * serv, Channel * c) {
- c->client_data = serv->client_data;
- c->cb = &serverccb;
- protocol_channel_opened(serv->client_data, c);
-}
-
-static ChannelServerCallbacks servercb = {
- discovery_new_connection
-};
-
-/*
- * Create a simple default discovery server if client did not provide one
- */
-void discovery_default_master_notifier(void) {
- PeerServer * ps;
- Protocol * proto;
- ChannelServer *serv;
-
- trace(LOG_DISCOVERY, "discovery_default_master_notifier");
- ps = channel_peer_from_url(DEFAULT_DISCOVERY_URL);
- if (ps == NULL) {
- trace(LOG_ALWAYS, "invalid discovery server URL\n");
- return;
- }
- ps->flags |= PS_FLAG_PRIVATE;
- proto = protocol_alloc();
- serv = channel_server(ps, &servercb, proto);
- if (serv == NULL) {
- trace(LOG_ALWAYS, "cannot create TCF discovery server\n");
- protocol_free(proto);
- return;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Implements discovery.
+ */
+
+#if _WRS_KERNEL
+# include <vxWorks.h>
+#endif
+#include <stddef.h>
+#include <errno.h>
+#include <assert.h>
+#include "mdep.h"
+#include "tcf.h"
+#include "discovery.h"
+#include "protocol.h"
+#include "channel.h"
+#include "myalloc.h"
+#include "events.h"
+#include "trace.h"
+#include "exceptions.h"
+#include "json.h"
+#include "peer.h"
+
+/*
+ * Channel callback handlers
+ */
+static void channel_server_connecting(Channel *c) {
+ trace(LOG_DISCOVERY, "discovery_help: channel_server_connecting");
+
+ send_hello_message(c->client_data, c);
+ discovery_channel_add(c);
+ c->out.flush(&c->out);
+}
+
+static void channel_server_connected(Channel *c) {
+ int i;
+
+ trace(LOG_DISCOVERY, "discovery_help: channel_server_connected, peer services:");
+ for (i = 0; i < c->peer_service_cnt; i++) {
+ trace(LOG_DISCOVERY, " %s", c->peer_service_list[i]);
+ }
+}
+
+static void channel_server_receive(Channel *c) {
+ handle_protocol_message(c->client_data, c);
+}
+
+static void channel_server_disconnected(Channel *c) {
+ trace(LOG_DISCOVERY, "discovery_help: channel_server_disconnected\n");
+ discovery_channel_remove(c);
+ protocol_channel_closed(c->client_data, c);
+}
+
+static ChannelCallbacks serverccb = {
+ channel_server_connecting,
+ channel_server_connected,
+ channel_server_receive,
+ channel_server_disconnected
+};
+
+/*
+ * New incomming connection
+ */
+static void discovery_new_connection(ChannelServer * serv, Channel * c) {
+ c->client_data = serv->client_data;
+ c->cb = &serverccb;
+ protocol_channel_opened(serv->client_data, c);
+}
+
+static ChannelServerCallbacks servercb = {
+ discovery_new_connection
+};
+
+/*
+ * Create a simple default discovery server if client did not provide one
+ */
+void discovery_default_master_notifier(void) {
+ PeerServer * ps;
+ Protocol * proto;
+ ChannelServer *serv;
+
+ trace(LOG_DISCOVERY, "discovery_default_master_notifier");
+ ps = channel_peer_from_url(DEFAULT_DISCOVERY_URL);
+ if (ps == NULL) {
+ trace(LOG_ALWAYS, "invalid discovery server URL\n");
+ return;
+ }
+ ps->flags |= PS_FLAG_PRIVATE;
+ proto = protocol_alloc();
+ serv = channel_server(ps, &servercb, proto);
+ if (serv == NULL) {
+ trace(LOG_ALWAYS, "cannot create TCF discovery server\n");
+ protocol_free(proto);
+ return;
+ }
+}
diff --git a/discovery_help.h b/discovery_help.h
index baf4e54a..0ea037f4 100644
--- a/discovery_help.h
+++ b/discovery_help.h
@@ -1,25 +1,25 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Discovery helper interface
- */
-
-#ifndef D_discovery_help
-#define D_discovery_help
-
-/*
- * Default discovery master notifier that creates a simple server
- * supporting only basic services needed for discovery
- */
-extern void discovery_default_master_notifier(void);
-
-#endif
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Discovery helper interface
+ */
+
+#ifndef D_discovery_help
+#define D_discovery_help
+
+/*
+ * Default discovery master notifier that creates a simple server
+ * supporting only basic services needed for discovery
+ */
+extern void discovery_default_master_notifier(void);
+
+#endif
diff --git a/discovery_udp.c b/discovery_udp.c
index e14e1797..7e238663 100644
--- a/discovery_udp.c
+++ b/discovery_udp.c
@@ -1,413 +1,413 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Implements simple UDP based auto discovery.
- */
-
-#if defined(_WRS_KERNEL)
-# include <vxWorks.h>
-# include <inetLib.h>
-#endif
-#include <stddef.h>
-#include <errno.h>
-#include <assert.h>
-#include "mdep.h"
-#include "tcf.h"
-#include "discovery.h"
-#include "discovery_udp.h"
-#include "myalloc.h"
-#include "events.h"
-#include "errors.h"
-#include "trace.h"
-#include "peer.h"
-#include "ip_ifc.h"
-
-#define MAX_PENDING_INFO_REQ 10
-#define MAX_PENDING_INFO_ACK 10
-#define MAX_IFC 10
-
-#define REFRESH_TIME 10
-#define REFRESH_MIN_TIME 2
-#define STALE_TIME_DELTA (REFRESH_TIME*3)
-
-typedef struct receive_message receive_message;
-
-struct receive_message {
- int addr_len;
- int buf_len;
- struct sockaddr_in addr;
- char buf[PKT_SIZE];
-};
-
-static int ifcind;
-static ip_ifc_info ifclist[MAX_IFC];
-static int refresh_timer_active;
-static time_t last_refresh_time;
-static int pending_info_req;
-static int pending_info_ack;
-static int discovery_port;
-static int udp_server_socket = -1;
-static pthread_t udp_server_thread = 0;
-static pthread_mutex_t udp_discovery_mutex;
-
-#define MAX(x,y) ((x) > (y) ? (x) : (y))
-
-static void app_char(char * buf, int * pos, char ch) {
- if (*pos < PKT_SIZE) buf[*pos] = ch;
- (*pos)++;
-}
-
-static void app_str(char * buf, int * pos, char * str) {
- while (*str) {
- if (*pos < PKT_SIZE) buf[*pos] = *str;
- (*pos)++;
- str++;
- }
-}
-
-static void app_strz(char * buf, int * pos, char * str) {
- app_str(buf, pos, str);
- app_char(buf, pos, 0);
-}
-
-static int udp_send_peer_sever(PeerServer * ps, void * arg) {
- struct sockaddr_in *addr = arg;
- int i;
- int pos = 0;
- char * transport = NULL;
- char * host = NULL;
- char * port = NULL;
- int seenName = 0;
- int seenOSName = 0;
- ip_ifc_info *ifc;
- struct in_addr src_addr;
- struct sockaddr_in *dst_addr;
- struct sockaddr_in dst_addr_buf;
- char buf[PKT_SIZE];
-
- if ((ps->flags & (PS_FLAG_LOCAL | PS_FLAG_PRIVATE | PS_FLAG_DISCOVERABLE)) !=
- (PS_FLAG_LOCAL | PS_FLAG_DISCOVERABLE)) {
- return 0;
- }
- transport = peer_server_getprop(ps, "TransportName", "");
- if (strcmp(transport, "TCP") != 0 && strcmp(transport, "UDP") != 0) return 0;
- host = peer_server_getprop(ps, "Host", NULL);
-#ifdef _WRS_KERNEL
- // VxWorks inet_aton() return codes are opposite to standard
- if (host == NULL || inet_aton(host, &src_addr) != OK) return 0;
-#else
- if (host == NULL || inet_aton(host, &src_addr) == 0) return 0;
-#endif
- port = peer_server_getprop(ps, "Port", NULL);
- if (port == NULL) return 0;
-
- for (ifc = ifclist; ifc < &ifclist[ifcind]; ifc++) {
- if (src_addr.s_addr != INADDR_ANY &&
- (ifc->addr & ifc->mask) != (src_addr.s_addr & ifc->mask)) {
- /* Server address not matching this interface */
- continue;
- }
- if (addr != NULL &&
- (ifc->addr & ifc->mask) != (addr->sin_addr.s_addr & ifc->mask)) {
- /* Requesting address not matching this interface */
- continue;
- }
- if (addr == NULL) {
- dst_addr = &dst_addr_buf;
- memset(&dst_addr_buf, 0, sizeof dst_addr_buf);
- dst_addr->sin_family = AF_INET;
- dst_addr->sin_port = htons((short)discovery_port);
- dst_addr->sin_addr.s_addr = ifc->addr | ~ifc->mask;
- }
- else {
- dst_addr = addr;
- }
- trace(LOG_DISCOVERY, "udp_send_peer_sever: sending UDP_ACK_INFO, ID=%s:%s:%s, dst=%s", transport, host, port, inet_ntoa(dst_addr->sin_addr));
-
- buf[pos++] = 'T';
- buf[pos++] = 'C';
- buf[pos++] = 'F';
- buf[pos++] = '1';
- buf[pos++] = UDP_ACK_INFO;
- buf[pos++] = 0;
- buf[pos++] = 0;
- buf[pos++] = 0;
- app_str(buf, &pos, "ID=");
- app_str(buf, &pos, transport);
- app_str(buf, &pos, ":");
- app_str(buf, &pos, host);
- app_str(buf, &pos, ":");
- app_strz(buf, &pos, port);
- for (i = 0; i < ps->ind; i++) {
- char *name = ps->list[i].name;
- if (strcmp(name, "ID") == 0) continue;
- app_str(buf, &pos, name);
- app_char(buf, &pos, '=');
- if (strcmp(name, "Name") == 0) {
- seenName = 1;
- }
- if (strcmp(name, "OSName") == 0) {
- seenOSName = 1;
- }
- app_strz(buf, &pos, ps->list[i].value);
- }
- if (!seenName) {
- app_strz(buf, &pos, "Name=TCF Agent");
- }
- if (!seenOSName) {
- app_str(buf, &pos, "OSName=");
- app_strz(buf, &pos, get_os_name());
- }
- if (sendto(udp_server_socket, buf, pos, 0, (struct sockaddr *)dst_addr, sizeof *dst_addr) < 0) {
- trace(LOG_ALWAYS, "Can't send UDP packet to %s: %s",
- inet_ntoa(dst_addr->sin_addr), errno_to_str(errno));
- }
- }
- return 0;
-}
-
-static void udp_send_ack(struct sockaddr_in * addr) {
- assert(is_dispatch_thread());
- ifcind = build_ifclist(udp_server_socket, MAX_IFC, ifclist);
- peer_server_iter(udp_send_peer_sever, addr);
-}
-
-static void udp_send_req(void) {
- int i = 0;
- char buf[PKT_SIZE];
- struct sockaddr_in dst_addr;
-
- trace(LOG_DISCOVERY, "udp_send_req: sending UDP_REQ_INFO");
- memset(&dst_addr, 0, sizeof dst_addr);
- dst_addr.sin_family = AF_INET;
- dst_addr.sin_port = htons((short)discovery_port);
- dst_addr.sin_addr.s_addr = INADDR_BROADCAST;
-
- buf[i++] = 'T';
- buf[i++] = 'C';
- buf[i++] = 'F';
- buf[i++] = '1';
- buf[i++] = UDP_REQ_INFO;
- buf[i++] = 0;
- buf[i++] = 0;
- buf[i++] = 0;
- if (sendto(udp_server_socket, buf, i, 0, (struct sockaddr *)&dst_addr, sizeof dst_addr) < 0) {
- trace(LOG_ALWAYS, "Can't send UDP packet to %s: %s",
- inet_ntoa(dst_addr.sin_addr), errno_to_str(errno));
- }
-}
-
-static void udp_refresh_info(void * arg) {
- int implcit_refresh = (int)arg;
- time_t timenow = time(0);
- int delta;
-
- assert(is_dispatch_thread());
- trace(LOG_DISCOVERY, "udp_refresh_info, implcit %d, active %d, timenow %ld, last_refresh_time %ld", implcit_refresh, refresh_timer_active, timenow, last_refresh_time);
- if (implcit_refresh) {
- assert(refresh_timer_active);
- if ((delta = timenow - last_refresh_time) < REFRESH_TIME) {
- /* Recent explicit refresh - wait a little longer */
- assert(delta > 0);
- post_event_with_delay(udp_refresh_info, (void *)1, (REFRESH_TIME - delta)*1000*1000);
- return;
- }
- refresh_timer_active = 0;
- }
- else if (refresh_timer_active && last_refresh_time + REFRESH_MIN_TIME < timenow) {
- /* Less than 2 seconds since last refresh - ignore */
- return;
- }
- if (udp_server_socket < 0) {
- /* Server closed */
- return;
- }
- udp_send_ack(NULL);
- udp_send_req();
- last_refresh_time = timenow;
- if (!refresh_timer_active) {
- refresh_timer_active = 1;
- post_event_with_delay(udp_refresh_info, (void *)1, REFRESH_TIME*1000*1000);
- }
-}
-
-static void udp_receive_req(void * arg) {
- receive_message * m = arg;
-
- udp_send_ack(&m->addr);
- loc_free(m);
-
- pthread_mutex_lock(&udp_discovery_mutex);
- pending_info_req--;
- pthread_mutex_unlock(&udp_discovery_mutex);
-}
-
-static int is_remote_host(struct in_addr inaddr) {
- int i;
-
- for (i = 0; i < ifcind; i++) {
- if (inaddr.s_addr == ifclist[i].addr) {
- return 0;
- }
- }
- return 1;
-}
-
-static void udp_receive_ack(void * arg) {
- receive_message * m = arg;
- PeerServer * ps = peer_server_alloc();
- char * p = m->buf + 8;
- char * e = m->buf + m->buf_len;
- char * name;
- char * value;
-
- assert(is_dispatch_thread());
- while (p < e) {
- name = p;
- while (p < e && *p != '\0' && *p != '=') p++;
- if (p >= e || *p != '=') {
- p = NULL;
- break;
- }
- *p++ = '\0';
- value = p;
- while (p < e && *p != '\0') p++;
- if (p >= e) {
- p = NULL;
- break;
- }
- peer_server_addprop(ps, loc_strdup(name), loc_strdup(value));
- p++;
- }
- if (p != NULL && ps->id != NULL) {
- trace(LOG_DISCOVERY, "udp_receive_ack: received UDP_ACK_INFO, ID=%s", ps->id);
- peer_server_add(ps, STALE_TIME_DELTA);
- }
- else {
- trace(LOG_ALWAYS, "Received malformed UDP ACK packet");
- peer_server_free(ps);
- }
- loc_free(m);
-
- pthread_mutex_lock(&udp_discovery_mutex);
- pending_info_ack--;
- pthread_mutex_unlock(&udp_discovery_mutex);
-}
-
-static void * udp_server_socket_handler(void * x) {
- post_event(udp_refresh_info, NULL);
- for (;;) {
- receive_message * m = loc_alloc(sizeof *m);
- memset(&m->addr, 0, sizeof m->addr);
- m->addr_len = sizeof m->addr;
- m->buf_len = recvfrom(udp_server_socket, m->buf, sizeof m->buf, 0,
- (struct sockaddr *)&m->addr, &m->addr_len);
- if (m->buf_len < 0) {
- trace(LOG_ALWAYS, "UDP socket receive failed: %s", errno_to_str(errno));
- continue;
- }
- if (m->buf_len < 8 || strncmp(m->buf, "TCF1", 4) != 0) {
- trace(LOG_ALWAYS, "Received malformed UDP packet");
- continue;
- }
- pthread_mutex_lock(&udp_discovery_mutex);
- if (m->buf[4] == UDP_REQ_INFO &&
- pending_info_req < MAX_PENDING_INFO_REQ &&
- is_remote_host(m->addr.sin_addr)) {
- pending_info_req++;
- post_event(udp_receive_req, m);
- }
- else if (m->buf[4] == UDP_ACK_INFO && pending_info_ack < MAX_PENDING_INFO_ACK) {
- pending_info_ack++;
- post_event(udp_receive_ack, m);
- }
- else {
- loc_free(m);
- }
- pthread_mutex_unlock(&udp_discovery_mutex);
- }
- return NULL;
-}
-
-static void local_server_change(PeerServer * ps, int changeType, void * arg) {
- trace(LOG_ALWAYS, "local_server_change: ps=0x%x, type=%d, arg=0x%x", ps, changeType, arg);
- if (changeType > 0) {
- /* Boardcast information about new peers */
- udp_send_peer_sever(ps, NULL);
- }
-}
-
-int discovery_udp_server(const char * port) {
- int sock;
- int error;
- char *reason;
- const int i = 1;
- struct addrinfo hints;
- struct addrinfo * reslist = NULL;
- struct addrinfo * res = NULL;
-
- pthread_mutex_init(&udp_discovery_mutex, NULL);
- if (port == NULL) port = DISCOVERY_TCF_PORT;
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_protocol = IPPROTO_UDP;
- hints.ai_flags = AI_PASSIVE;
- error = loc_getaddrinfo(NULL, port, &hints, &reslist);
- if (error) {
- trace(LOG_ALWAYS, "getaddrinfo error: %s", loc_gai_strerror(error));
- return error;
- }
- sock = -1;
- reason = NULL;
- for (res = reslist; res != NULL; res = res->ai_next) {
- sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (sock < 0) {
- error = errno;
- reason = "create";
- continue;
- }
- if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0) {
- error = errno;
- reason = "setsockopt(SO_BROADCAST)";
- closesocket(sock);
- sock = -1;
- continue;
- }
- if (bind(sock, res->ai_addr, res->ai_addrlen)) {
- error = errno;
- reason = "bind";
- closesocket(sock);
- sock = -1;
- continue;
- }
- /* Only bind once - don't see how getaddrinfo with the given
- * arguments could return more then one anyway */
- break;
- }
- if (sock < 0) {
- trace(LOG_ALWAYS, "socket %s error: %s", reason, errno_to_str(error));
- loc_freeaddrinfo(reslist);
- return error;
- }
- discovery_port = ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port);
- loc_freeaddrinfo(reslist);
-
- udp_server_socket = sock;
- ifcind = build_ifclist(udp_server_socket, MAX_IFC, ifclist);
- if ((error = pthread_create(&udp_server_thread, &pthread_create_attr, udp_server_socket_handler, 0)) != 0) {
- trace(LOG_ALWAYS, "can't create a thread: %s", errno_to_str(error));
- return error;
- }
- peer_server_add_listener(local_server_change, NULL);
- return 0;
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Implements simple UDP based auto discovery.
+ */
+
+#if defined(_WRS_KERNEL)
+# include <vxWorks.h>
+# include <inetLib.h>
+#endif
+#include <stddef.h>
+#include <errno.h>
+#include <assert.h>
+#include "mdep.h"
+#include "tcf.h"
+#include "discovery.h"
+#include "discovery_udp.h"
+#include "myalloc.h"
+#include "events.h"
+#include "errors.h"
+#include "trace.h"
+#include "peer.h"
+#include "ip_ifc.h"
+
+#define MAX_PENDING_INFO_REQ 10
+#define MAX_PENDING_INFO_ACK 10
+#define MAX_IFC 10
+
+#define REFRESH_TIME 10
+#define REFRESH_MIN_TIME 2
+#define STALE_TIME_DELTA (REFRESH_TIME*3)
+
+typedef struct receive_message receive_message;
+
+struct receive_message {
+ int addr_len;
+ int buf_len;
+ struct sockaddr_in addr;
+ char buf[PKT_SIZE];
+};
+
+static int ifcind;
+static ip_ifc_info ifclist[MAX_IFC];
+static int refresh_timer_active;
+static time_t last_refresh_time;
+static int pending_info_req;
+static int pending_info_ack;
+static int discovery_port;
+static int udp_server_socket = -1;
+static pthread_t udp_server_thread = 0;
+static pthread_mutex_t udp_discovery_mutex;
+
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+
+static void app_char(char * buf, int * pos, char ch) {
+ if (*pos < PKT_SIZE) buf[*pos] = ch;
+ (*pos)++;
+}
+
+static void app_str(char * buf, int * pos, char * str) {
+ while (*str) {
+ if (*pos < PKT_SIZE) buf[*pos] = *str;
+ (*pos)++;
+ str++;
+ }
+}
+
+static void app_strz(char * buf, int * pos, char * str) {
+ app_str(buf, pos, str);
+ app_char(buf, pos, 0);
+}
+
+static int udp_send_peer_sever(PeerServer * ps, void * arg) {
+ struct sockaddr_in *addr = arg;
+ int i;
+ int pos = 0;
+ char * transport = NULL;
+ char * host = NULL;
+ char * port = NULL;
+ int seenName = 0;
+ int seenOSName = 0;
+ ip_ifc_info *ifc;
+ struct in_addr src_addr;
+ struct sockaddr_in *dst_addr;
+ struct sockaddr_in dst_addr_buf;
+ char buf[PKT_SIZE];
+
+ if ((ps->flags & (PS_FLAG_LOCAL | PS_FLAG_PRIVATE | PS_FLAG_DISCOVERABLE)) !=
+ (PS_FLAG_LOCAL | PS_FLAG_DISCOVERABLE)) {
+ return 0;
+ }
+ transport = peer_server_getprop(ps, "TransportName", "");
+ if (strcmp(transport, "TCP") != 0 && strcmp(transport, "UDP") != 0) return 0;
+ host = peer_server_getprop(ps, "Host", NULL);
+#ifdef _WRS_KERNEL
+ // VxWorks inet_aton() return codes are opposite to standard
+ if (host == NULL || inet_aton(host, &src_addr) != OK) return 0;
+#else
+ if (host == NULL || inet_aton(host, &src_addr) == 0) return 0;
+#endif
+ port = peer_server_getprop(ps, "Port", NULL);
+ if (port == NULL) return 0;
+
+ for (ifc = ifclist; ifc < &ifclist[ifcind]; ifc++) {
+ if (src_addr.s_addr != INADDR_ANY &&
+ (ifc->addr & ifc->mask) != (src_addr.s_addr & ifc->mask)) {
+ /* Server address not matching this interface */
+ continue;
+ }
+ if (addr != NULL &&
+ (ifc->addr & ifc->mask) != (addr->sin_addr.s_addr & ifc->mask)) {
+ /* Requesting address not matching this interface */
+ continue;
+ }
+ if (addr == NULL) {
+ dst_addr = &dst_addr_buf;
+ memset(&dst_addr_buf, 0, sizeof dst_addr_buf);
+ dst_addr->sin_family = AF_INET;
+ dst_addr->sin_port = htons((short)discovery_port);
+ dst_addr->sin_addr.s_addr = ifc->addr | ~ifc->mask;
+ }
+ else {
+ dst_addr = addr;
+ }
+ trace(LOG_DISCOVERY, "udp_send_peer_sever: sending UDP_ACK_INFO, ID=%s:%s:%s, dst=%s", transport, host, port, inet_ntoa(dst_addr->sin_addr));
+
+ buf[pos++] = 'T';
+ buf[pos++] = 'C';
+ buf[pos++] = 'F';
+ buf[pos++] = '1';
+ buf[pos++] = UDP_ACK_INFO;
+ buf[pos++] = 0;
+ buf[pos++] = 0;
+ buf[pos++] = 0;
+ app_str(buf, &pos, "ID=");
+ app_str(buf, &pos, transport);
+ app_str(buf, &pos, ":");
+ app_str(buf, &pos, host);
+ app_str(buf, &pos, ":");
+ app_strz(buf, &pos, port);
+ for (i = 0; i < ps->ind; i++) {
+ char *name = ps->list[i].name;
+ if (strcmp(name, "ID") == 0) continue;
+ app_str(buf, &pos, name);
+ app_char(buf, &pos, '=');
+ if (strcmp(name, "Name") == 0) {
+ seenName = 1;
+ }
+ if (strcmp(name, "OSName") == 0) {
+ seenOSName = 1;
+ }
+ app_strz(buf, &pos, ps->list[i].value);
+ }
+ if (!seenName) {
+ app_strz(buf, &pos, "Name=TCF Agent");
+ }
+ if (!seenOSName) {
+ app_str(buf, &pos, "OSName=");
+ app_strz(buf, &pos, get_os_name());
+ }
+ if (sendto(udp_server_socket, buf, pos, 0, (struct sockaddr *)dst_addr, sizeof *dst_addr) < 0) {
+ trace(LOG_ALWAYS, "Can't send UDP packet to %s: %s",
+ inet_ntoa(dst_addr->sin_addr), errno_to_str(errno));
+ }
+ }
+ return 0;
+}
+
+static void udp_send_ack(struct sockaddr_in * addr) {
+ assert(is_dispatch_thread());
+ ifcind = build_ifclist(udp_server_socket, MAX_IFC, ifclist);
+ peer_server_iter(udp_send_peer_sever, addr);
+}
+
+static void udp_send_req(void) {
+ int i = 0;
+ char buf[PKT_SIZE];
+ struct sockaddr_in dst_addr;
+
+ trace(LOG_DISCOVERY, "udp_send_req: sending UDP_REQ_INFO");
+ memset(&dst_addr, 0, sizeof dst_addr);
+ dst_addr.sin_family = AF_INET;
+ dst_addr.sin_port = htons((short)discovery_port);
+ dst_addr.sin_addr.s_addr = INADDR_BROADCAST;
+
+ buf[i++] = 'T';
+ buf[i++] = 'C';
+ buf[i++] = 'F';
+ buf[i++] = '1';
+ buf[i++] = UDP_REQ_INFO;
+ buf[i++] = 0;
+ buf[i++] = 0;
+ buf[i++] = 0;
+ if (sendto(udp_server_socket, buf, i, 0, (struct sockaddr *)&dst_addr, sizeof dst_addr) < 0) {
+ trace(LOG_ALWAYS, "Can't send UDP packet to %s: %s",
+ inet_ntoa(dst_addr.sin_addr), errno_to_str(errno));
+ }
+}
+
+static void udp_refresh_info(void * arg) {
+ int implcit_refresh = (int)arg;
+ time_t timenow = time(0);
+ int delta;
+
+ assert(is_dispatch_thread());
+ trace(LOG_DISCOVERY, "udp_refresh_info, implcit %d, active %d, timenow %ld, last_refresh_time %ld", implcit_refresh, refresh_timer_active, timenow, last_refresh_time);
+ if (implcit_refresh) {
+ assert(refresh_timer_active);
+ if ((delta = timenow - last_refresh_time) < REFRESH_TIME) {
+ /* Recent explicit refresh - wait a little longer */
+ assert(delta > 0);
+ post_event_with_delay(udp_refresh_info, (void *)1, (REFRESH_TIME - delta)*1000*1000);
+ return;
+ }
+ refresh_timer_active = 0;
+ }
+ else if (refresh_timer_active && last_refresh_time + REFRESH_MIN_TIME < timenow) {
+ /* Less than 2 seconds since last refresh - ignore */
+ return;
+ }
+ if (udp_server_socket < 0) {
+ /* Server closed */
+ return;
+ }
+ udp_send_ack(NULL);
+ udp_send_req();
+ last_refresh_time = timenow;
+ if (!refresh_timer_active) {
+ refresh_timer_active = 1;
+ post_event_with_delay(udp_refresh_info, (void *)1, REFRESH_TIME*1000*1000);
+ }
+}
+
+static void udp_receive_req(void * arg) {
+ receive_message * m = arg;
+
+ udp_send_ack(&m->addr);
+ loc_free(m);
+
+ pthread_mutex_lock(&udp_discovery_mutex);
+ pending_info_req--;
+ pthread_mutex_unlock(&udp_discovery_mutex);
+}
+
+static int is_remote_host(struct in_addr inaddr) {
+ int i;
+
+ for (i = 0; i < ifcind; i++) {
+ if (inaddr.s_addr == ifclist[i].addr) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void udp_receive_ack(void * arg) {
+ receive_message * m = arg;
+ PeerServer * ps = peer_server_alloc();
+ char * p = m->buf + 8;
+ char * e = m->buf + m->buf_len;
+ char * name;
+ char * value;
+
+ assert(is_dispatch_thread());
+ while (p < e) {
+ name = p;
+ while (p < e && *p != '\0' && *p != '=') p++;
+ if (p >= e || *p != '=') {
+ p = NULL;
+ break;
+ }
+ *p++ = '\0';
+ value = p;
+ while (p < e && *p != '\0') p++;
+ if (p >= e) {
+ p = NULL;
+ break;
+ }
+ peer_server_addprop(ps, loc_strdup(name), loc_strdup(value));
+ p++;
+ }
+ if (p != NULL && ps->id != NULL) {
+ trace(LOG_DISCOVERY, "udp_receive_ack: received UDP_ACK_INFO, ID=%s", ps->id);
+ peer_server_add(ps, STALE_TIME_DELTA);
+ }
+ else {
+ trace(LOG_ALWAYS, "Received malformed UDP ACK packet");
+ peer_server_free(ps);
+ }
+ loc_free(m);
+
+ pthread_mutex_lock(&udp_discovery_mutex);
+ pending_info_ack--;
+ pthread_mutex_unlock(&udp_discovery_mutex);
+}
+
+static void * udp_server_socket_handler(void * x) {
+ post_event(udp_refresh_info, NULL);
+ for (;;) {
+ receive_message * m = loc_alloc(sizeof *m);
+ memset(&m->addr, 0, sizeof m->addr);
+ m->addr_len = sizeof m->addr;
+ m->buf_len = recvfrom(udp_server_socket, m->buf, sizeof m->buf, 0,
+ (struct sockaddr *)&m->addr, &m->addr_len);
+ if (m->buf_len < 0) {
+ trace(LOG_ALWAYS, "UDP socket receive failed: %s", errno_to_str(errno));
+ continue;
+ }
+ if (m->buf_len < 8 || strncmp(m->buf, "TCF1", 4) != 0) {
+ trace(LOG_ALWAYS, "Received malformed UDP packet");
+ continue;
+ }
+ pthread_mutex_lock(&udp_discovery_mutex);
+ if (m->buf[4] == UDP_REQ_INFO &&
+ pending_info_req < MAX_PENDING_INFO_REQ &&
+ is_remote_host(m->addr.sin_addr)) {
+ pending_info_req++;
+ post_event(udp_receive_req, m);
+ }
+ else if (m->buf[4] == UDP_ACK_INFO && pending_info_ack < MAX_PENDING_INFO_ACK) {
+ pending_info_ack++;
+ post_event(udp_receive_ack, m);
+ }
+ else {
+ loc_free(m);
+ }
+ pthread_mutex_unlock(&udp_discovery_mutex);
+ }
+ return NULL;
+}
+
+static void local_server_change(PeerServer * ps, int changeType, void * arg) {
+ trace(LOG_ALWAYS, "local_server_change: ps=0x%x, type=%d, arg=0x%x", ps, changeType, arg);
+ if (changeType > 0) {
+ /* Boardcast information about new peers */
+ udp_send_peer_sever(ps, NULL);
+ }
+}
+
+int discovery_udp_server(const char * port) {
+ int sock;
+ int error;
+ char *reason;
+ const int i = 1;
+ struct addrinfo hints;
+ struct addrinfo * reslist = NULL;
+ struct addrinfo * res = NULL;
+
+ pthread_mutex_init(&udp_discovery_mutex, NULL);
+ if (port == NULL) port = DISCOVERY_TCF_PORT;
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_PASSIVE;
+ error = loc_getaddrinfo(NULL, port, &hints, &reslist);
+ if (error) {
+ trace(LOG_ALWAYS, "getaddrinfo error: %s", loc_gai_strerror(error));
+ return error;
+ }
+ sock = -1;
+ reason = NULL;
+ for (res = reslist; res != NULL; res = res->ai_next) {
+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sock < 0) {
+ error = errno;
+ reason = "create";
+ continue;
+ }
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0) {
+ error = errno;
+ reason = "setsockopt(SO_BROADCAST)";
+ closesocket(sock);
+ sock = -1;
+ continue;
+ }
+ if (bind(sock, res->ai_addr, res->ai_addrlen)) {
+ error = errno;
+ reason = "bind";
+ closesocket(sock);
+ sock = -1;
+ continue;
+ }
+ /* Only bind once - don't see how getaddrinfo with the given
+ * arguments could return more then one anyway */
+ break;
+ }
+ if (sock < 0) {
+ trace(LOG_ALWAYS, "socket %s error: %s", reason, errno_to_str(error));
+ loc_freeaddrinfo(reslist);
+ return error;
+ }
+ discovery_port = ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port);
+ loc_freeaddrinfo(reslist);
+
+ udp_server_socket = sock;
+ ifcind = build_ifclist(udp_server_socket, MAX_IFC, ifclist);
+ if ((error = pthread_create(&udp_server_thread, &pthread_create_attr, udp_server_socket_handler, 0)) != 0) {
+ trace(LOG_ALWAYS, "can't create a thread: %s", errno_to_str(error));
+ return error;
+ }
+ peer_server_add_listener(local_server_change, NULL);
+ return 0;
+}
diff --git a/discovery_udp.h b/discovery_udp.h
index feba43c3..325346b0 100644
--- a/discovery_udp.h
+++ b/discovery_udp.h
@@ -1,24 +1,24 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Simple UDP based discovery server interface
- */
-
-#ifndef D_discovery_udp
-#define D_discovery_udp
-
-/*
- * Start discovery server
- */
-extern int discovery_udp_server(const char *port);
-
-#endif
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Simple UDP based discovery server interface
+ */
+
+#ifndef D_discovery_udp
+#define D_discovery_udp
+
+/*
+ * Start discovery server
+ */
+extern int discovery_udp_server(const char *port);
+
+#endif
diff --git a/dwarf.h b/dwarf.h
index edb0f988..79ef4146 100644
--- a/dwarf.h
+++ b/dwarf.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1996 - 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 1996, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/dwarfio.c b/dwarfio.c
index 7295cf39..8a9d9cce 100644
--- a/dwarfio.c
+++ b/dwarfio.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006-2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/dwarfio.h b/dwarfio.h
index 395c08fb..f45edb1c 100644
--- a/dwarfio.h
+++ b/dwarfio.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006-2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/elf.c b/elf.c
index 7016abe6..cb1b386f 100644
--- a/elf.c
+++ b/elf.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/elf.h b/elf.h
index dc39a08f..a383033f 100644
--- a/elf.h
+++ b/elf.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/errors.c b/errors.c
index 691f9bec..a4914415 100644
--- a/errors.c
+++ b/errors.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/errors.h b/errors.h
index cf102583..b8e39045 100644
--- a/errors.h
+++ b/errors.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/events.c b/events.c
index d29f1020..16e2465d 100644
--- a/events.c
+++ b/events.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/events.h b/events.h
index d54ba01b..31300bbe 100644
--- a/events.h
+++ b/events.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/exceptions.c b/exceptions.c
index 2941bec6..9b947226 100644
--- a/exceptions.c
+++ b/exceptions.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/exceptions.h b/exceptions.h
index 8c2a54f8..1034d429 100644
--- a/exceptions.h
+++ b/exceptions.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/expressions.c b/expressions.c
index fa943578..ec6b8298 100644
--- a/expressions.c
+++ b/expressions.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/expressions.h b/expressions.h
index 8fcb43c1..9f031ded 100644
--- a/expressions.h
+++ b/expressions.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/filesystem.c b/filesystem.c
index 7c7666b6..0c7558ee 100644
--- a/filesystem.c
+++ b/filesystem.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/filesystem.h b/filesystem.h
index 9592168b..3e706896 100644
--- a/filesystem.h
+++ b/filesystem.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/ip_ifc.c b/ip_ifc.c
index 31e5e827..deddff4a 100644
--- a/ip_ifc.c
+++ b/ip_ifc.c
@@ -1,91 +1,91 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Implements IP interface list.
- */
-
-#if _WRS_KERNEL
-# include <vxWorks.h>
-#endif
-#include <stddef.h>
-#include <errno.h>
-#include <assert.h>
-#include "mdep.h"
-#include "ip_ifc.h"
-#include "myalloc.h"
-#include "events.h"
-#include "errors.h"
-#include "trace.h"
-
-#define MAX(x,y) ((x) > (y) ? (x) : (y))
-
-int build_ifclist(int sock, int max, ip_ifc_info *list) {
-#ifdef WIN32
- int i;
- int ind;
- MIB_IPADDRTABLE * info;
- ULONG out_buf_len;
- DWORD ret_val;
-
- out_buf_len = sizeof *info;
- info = (MIB_IPADDRTABLE *)loc_alloc(out_buf_len);
- ret_val = GetIpAddrTable(info, &out_buf_len, 0);
- if (ret_val == ERROR_INSUFFICIENT_BUFFER) {
- loc_free(info);
- info = (MIB_IPADDRTABLE *)loc_alloc(out_buf_len);
- ret_val = GetIpAddrTable(info, &out_buf_len, 0);
- }
- if (ret_val != NO_ERROR) {
- trace(LOG_ALWAYS, "GetIpAddrTable() error: %d", ret_val);
- loc_free(info);
- return 0;
- }
- ind = 0;
- for (i = 0; i < (int)info->dwNumEntries && ind < max; i++) {
- list[ind].addr = info->table[i].dwAddr;
- if (list[ind].addr == 0) continue;
- list[ind].mask = info->table[i].dwMask;
- ind++;
- }
- loc_free(info);
-#else
- int ind;
- char * cp;
- struct ifconf ifc;
- char if_bbf[0x2000];
-
- memset(&ifc, 0, sizeof ifc);
- ifc.ifc_len = sizeof if_bbf;
- ifc.ifc_buf = if_bbf;
- if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
- trace(LOG_ALWAYS, "error: ioctl(SIOCGIFCONF) returned %d: %s", errno, errno_to_str(errno));
- return;
- }
- ind = 0;
- cp = (char *)ifc.ifc_req;
- while (cp < (char *)ifc.ifc_req + ifc.ifc_len && ind < max) {
- struct ifreq * ifreq_addr = (struct ifreq *)cp;
- struct ifreq ifreq_mask = *ifreq_addr;
- cp += sizeof(ifreq_addr->ifr_name);
- cp += MAX(SA_LEN(&ifreq_addr->ifr_addr), sizeof(ifreq_addr->ifr_addr));
- if (ifreq_addr->ifr_addr.sa_family != AF_INET) continue;
- if (ioctl(sock, SIOCGIFNETMASK, &ifreq_mask) < 0) {
- trace(LOG_ALWAYS, "error: ioctl(SIOCGIFNETMASK) returned %d: %s", errno, errno_to_str(errno));
- continue;
- }
- list[ind].addr = ((struct sockaddr_in *)&ifreq_addr->ifr_addr)->sin_addr.s_addr;
- list[ind].mask = ((struct sockaddr_in *)&ifreq_mask.ifr_netmask)->sin_addr.s_addr;
- ind++;
- }
-#endif
- return ind;
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Implements IP interface list.
+ */
+
+#if _WRS_KERNEL
+# include <vxWorks.h>
+#endif
+#include <stddef.h>
+#include <errno.h>
+#include <assert.h>
+#include "mdep.h"
+#include "ip_ifc.h"
+#include "myalloc.h"
+#include "events.h"
+#include "errors.h"
+#include "trace.h"
+
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+
+int build_ifclist(int sock, int max, ip_ifc_info *list) {
+#ifdef WIN32
+ int i;
+ int ind;
+ MIB_IPADDRTABLE * info;
+ ULONG out_buf_len;
+ DWORD ret_val;
+
+ out_buf_len = sizeof *info;
+ info = (MIB_IPADDRTABLE *)loc_alloc(out_buf_len);
+ ret_val = GetIpAddrTable(info, &out_buf_len, 0);
+ if (ret_val == ERROR_INSUFFICIENT_BUFFER) {
+ loc_free(info);
+ info = (MIB_IPADDRTABLE *)loc_alloc(out_buf_len);
+ ret_val = GetIpAddrTable(info, &out_buf_len, 0);
+ }
+ if (ret_val != NO_ERROR) {
+ trace(LOG_ALWAYS, "GetIpAddrTable() error: %d", ret_val);
+ loc_free(info);
+ return 0;
+ }
+ ind = 0;
+ for (i = 0; i < (int)info->dwNumEntries && ind < max; i++) {
+ list[ind].addr = info->table[i].dwAddr;
+ if (list[ind].addr == 0) continue;
+ list[ind].mask = info->table[i].dwMask;
+ ind++;
+ }
+ loc_free(info);
+#else
+ int ind;
+ char * cp;
+ struct ifconf ifc;
+ char if_bbf[0x2000];
+
+ memset(&ifc, 0, sizeof ifc);
+ ifc.ifc_len = sizeof if_bbf;
+ ifc.ifc_buf = if_bbf;
+ if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
+ trace(LOG_ALWAYS, "error: ioctl(SIOCGIFCONF) returned %d: %s", errno, errno_to_str(errno));
+ return;
+ }
+ ind = 0;
+ cp = (char *)ifc.ifc_req;
+ while (cp < (char *)ifc.ifc_req + ifc.ifc_len && ind < max) {
+ struct ifreq * ifreq_addr = (struct ifreq *)cp;
+ struct ifreq ifreq_mask = *ifreq_addr;
+ cp += sizeof(ifreq_addr->ifr_name);
+ cp += MAX(SA_LEN(&ifreq_addr->ifr_addr), sizeof(ifreq_addr->ifr_addr));
+ if (ifreq_addr->ifr_addr.sa_family != AF_INET) continue;
+ if (ioctl(sock, SIOCGIFNETMASK, &ifreq_mask) < 0) {
+ trace(LOG_ALWAYS, "error: ioctl(SIOCGIFNETMASK) returned %d: %s", errno, errno_to_str(errno));
+ continue;
+ }
+ list[ind].addr = ((struct sockaddr_in *)&ifreq_addr->ifr_addr)->sin_addr.s_addr;
+ list[ind].mask = ((struct sockaddr_in *)&ifreq_mask.ifr_netmask)->sin_addr.s_addr;
+ ind++;
+ }
+#endif
+ return ind;
+}
diff --git a/ip_ifc.h b/ip_ifc.h
index 5b0a5c6b..3f41eb7c 100644
--- a/ip_ifc.h
+++ b/ip_ifc.h
@@ -1,30 +1,30 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * IP interface list
- */
-
-#ifndef D_ip_ifc
-#define D_ip_ifc
-
-typedef struct {
- unsigned long addr;
- unsigned long mask;
-} ip_ifc_info;
-
-/*
- * Build interface list for socket,
- * Return number of interfaces in the list.
- */
-extern int build_ifclist(int sock, int max, ip_ifc_info * list);
-
-#endif
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * IP interface list
+ */
+
+#ifndef D_ip_ifc
+#define D_ip_ifc
+
+typedef struct {
+ unsigned long addr;
+ unsigned long mask;
+} ip_ifc_info;
+
+/*
+ * Build interface list for socket,
+ * Return number of interfaces in the list.
+ */
+extern int build_ifclist(int sock, int max, ip_ifc_info * list);
+
+#endif
diff --git a/json.c b/json.c
index 9cb7a758..6232d6c2 100644
--- a/json.c
+++ b/json.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/json.h b/json.h
index 78d82460..59d0b0e5 100644
--- a/json.h
+++ b/json.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/linenumbers.c b/linenumbers.c
index dcf9e09f..9d05ec02 100644
--- a/linenumbers.c
+++ b/linenumbers.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/linenumbers.h b/linenumbers.h
index f9523f5e..04dc32c6 100644
--- a/linenumbers.h
+++ b/linenumbers.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/link.h b/link.h
index 40bbf58c..d8f7e4ab 100644
--- a/link.h
+++ b/link.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/main.c b/main.c
index d575fa4d..60cbcdb1 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/main_client.c b/main_client.c
index b6fab550..d414c6b6 100644
--- a/main_client.c
+++ b/main_client.c
@@ -1,129 +1,129 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Agent main module.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-#include <signal.h>
-#include "mdep.h"
-#include "events.h"
-#include "trace.h"
-#include "cmdline.h"
-#include "channel.h"
-#include "protocol.h"
-#include "proxy.h"
-#include "discovery_help.h"
-
-static char * progname;
-
-#if defined(_WRS_KERNEL)
-int tcf_client(void) {
-#else
-int main(int argc, char ** argv) {
-#endif
- int c;
- int ind;
- int error;
- char * s;
- char * log_name = 0;
- char * node = NULL;
- Protocol * proto;
-
-#ifndef WIN32
- signal(SIGPIPE, SIG_IGN);
-#endif
- ini_mdep();
- ini_trace();
- ini_events_queue();
-
-#if defined(_WRS_KERNEL)
-
- progname = "tcf";
- log_file = stdout;
- log_mode = 0;
-
-#else
-
- progname = argv[0];
-
- /* Parse arguments */
- for (ind = 1; ind < argc; ind++) {
- s = argv[ind];
- if (*s != '-') {
- break;
- }
- s++;
- while ((c = *s++) != '\0') {
- switch (c) {
- case 'l':
- case 'L':
- if (*s == '\0') {
- if (++ind >= argc) {
- fprintf(stderr, "%s: error: no argument given to option '%c'\n", progname, c);
- exit(1);
- }
- s = argv[ind];
- }
- switch (c) {
- case 'l':
- log_mode = strtol(s, 0, 0);
- break;
-
- case 'L':
- log_name = s;
- break;
-
- default:
- fprintf(stderr, "%s: error: illegal option '%c'\n", progname, c);
- exit(1);
- }
- s = "";
- break;
-
- default:
- fprintf(stderr, "%s: error: illegal option '%c'\n", progname, c);
- exit(1);
- }
- }
- }
-
- /* Create log file */
- if (log_name == 0) {
- log_file = NULL;
- }
- else if (strcmp(log_name, "-") == 0) {
- log_file = stderr;
- }
- else if ((log_file = fopen(log_name, "a")) == NULL) {
- fprintf(stderr, "%s: error: cannot create log file %s\n", progname, log_name);
- exit(1);
- }
-
-#endif
-
- ini_proxy_service();
- if (discovery_start(discovery_default_master_notifier)) {
- discovery_default_master_notifier();
- }
- ini_cmdline_handler();
-
- /* Process events - must run on the initial thread since ptrace()
- * returns ECHILD otherwise, thinking we are not the owner. */
- run_event_loop();
- return 0;
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Agent main module.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <signal.h>
+#include "mdep.h"
+#include "events.h"
+#include "trace.h"
+#include "cmdline.h"
+#include "channel.h"
+#include "protocol.h"
+#include "proxy.h"
+#include "discovery_help.h"
+
+static char * progname;
+
+#if defined(_WRS_KERNEL)
+int tcf_client(void) {
+#else
+int main(int argc, char ** argv) {
+#endif
+ int c;
+ int ind;
+ int error;
+ char * s;
+ char * log_name = 0;
+ char * node = NULL;
+ Protocol * proto;
+
+#ifndef WIN32
+ signal(SIGPIPE, SIG_IGN);
+#endif
+ ini_mdep();
+ ini_trace();
+ ini_events_queue();
+
+#if defined(_WRS_KERNEL)
+
+ progname = "tcf";
+ log_file = stdout;
+ log_mode = 0;
+
+#else
+
+ progname = argv[0];
+
+ /* Parse arguments */
+ for (ind = 1; ind < argc; ind++) {
+ s = argv[ind];
+ if (*s != '-') {
+ break;
+ }
+ s++;
+ while ((c = *s++) != '\0') {
+ switch (c) {
+ case 'l':
+ case 'L':
+ if (*s == '\0') {
+ if (++ind >= argc) {
+ fprintf(stderr, "%s: error: no argument given to option '%c'\n", progname, c);
+ exit(1);
+ }
+ s = argv[ind];
+ }
+ switch (c) {
+ case 'l':
+ log_mode = strtol(s, 0, 0);
+ break;
+
+ case 'L':
+ log_name = s;
+ break;
+
+ default:
+ fprintf(stderr, "%s: error: illegal option '%c'\n", progname, c);
+ exit(1);
+ }
+ s = "";
+ break;
+
+ default:
+ fprintf(stderr, "%s: error: illegal option '%c'\n", progname, c);
+ exit(1);
+ }
+ }
+ }
+
+ /* Create log file */
+ if (log_name == 0) {
+ log_file = NULL;
+ }
+ else if (strcmp(log_name, "-") == 0) {
+ log_file = stderr;
+ }
+ else if ((log_file = fopen(log_name, "a")) == NULL) {
+ fprintf(stderr, "%s: error: cannot create log file %s\n", progname, log_name);
+ exit(1);
+ }
+
+#endif
+
+ ini_proxy_service();
+ if (discovery_start(discovery_default_master_notifier)) {
+ discovery_default_master_notifier();
+ }
+ ini_cmdline_handler();
+
+ /* Process events - must run on the initial thread since ptrace()
+ * returns ECHILD otherwise, thinking we are not the owner. */
+ run_event_loop();
+ return 0;
+}
diff --git a/main_reg.c b/main_reg.c
index 3b2b390b..5027ff84 100644
--- a/main_reg.c
+++ b/main_reg.c
@@ -1,126 +1,126 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Agent main module.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-#include <signal.h>
-#include "mdep.h"
-#include "events.h"
-#include "trace.h"
-#include "cmdline.h"
-#include "channel.h"
-#include "discovery_help.h"
-#include "protocol.h"
-#include "proxy.h"
-#include "discovery.h"
-
-static char * progname;
-
-#if defined(_WRS_KERNEL)
-int tcf_registry(void) {
-#else
-int main(int argc, char **argv) {
-#endif
- int c;
- int ind;
- int error;
- char *s;
- char *log_name = 0;
-
-#ifndef WIN32
- signal(SIGPIPE, SIG_IGN);
-#endif
- ini_mdep();
- ini_trace();
- ini_events_queue();
-
-#if defined(_WRS_KERNEL)
-
- progname = "tcf";
- log_file = stdout;
- log_mode = 0;
-
-#else
-
- progname = argv[0];
-
- /* Parse arguments */
- for (ind = 1; ind < argc; ind++) {
- s = argv[ind];
- if (*s != '-') {
- break;
- }
- s++;
- while ((c = *s++) != '\0') {
- switch (c) {
- case 'l':
- case 'L':
- if (*s == '\0') {
- if (++ind >= argc) {
- fprintf(stderr, "%s: error: no argument given to option '%c'\n", progname, c);
- exit(1);
- }
- s = argv[ind];
- }
- switch (c) {
- case 'l':
- log_mode = strtol(s, 0, 0);
- break;
-
- case 'L':
- log_name = s;
- break;
-
- default:
- fprintf(stderr, "%s: error: illegal option '%c'\n", progname, c);
- exit(1);
- }
- s = "";
- break;
-
- default:
- fprintf(stderr, "%s: error: illegal option '%c'\n", progname, c);
- exit(1);
- }
- }
- }
-
- /* Create log file */
- if (log_name == 0) {
- log_file = NULL;
- }
- else if (strcmp(log_name, "-") == 0) {
- log_file = stderr;
- }
- else if ((log_file = fopen(log_name, "a")) == NULL) {
- fprintf(stderr, "%s: error: cannot create log file %s\n", progname, log_name);
- exit(1);
- }
-
-#endif
-
- if (discovery_start(discovery_default_master_notifier)) {
- discovery_default_master_notifier();
- }
-
- /* Process events - must run on the initial thread since ptrace()
- * returns ECHILD otherwise, thinking we are not the owner. */
- run_event_loop();
- return 0;
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Agent main module.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <signal.h>
+#include "mdep.h"
+#include "events.h"
+#include "trace.h"
+#include "cmdline.h"
+#include "channel.h"
+#include "discovery_help.h"
+#include "protocol.h"
+#include "proxy.h"
+#include "discovery.h"
+
+static char * progname;
+
+#if defined(_WRS_KERNEL)
+int tcf_registry(void) {
+#else
+int main(int argc, char **argv) {
+#endif
+ int c;
+ int ind;
+ int error;
+ char *s;
+ char *log_name = 0;
+
+#ifndef WIN32
+ signal(SIGPIPE, SIG_IGN);
+#endif
+ ini_mdep();
+ ini_trace();
+ ini_events_queue();
+
+#if defined(_WRS_KERNEL)
+
+ progname = "tcf";
+ log_file = stdout;
+ log_mode = 0;
+
+#else
+
+ progname = argv[0];
+
+ /* Parse arguments */
+ for (ind = 1; ind < argc; ind++) {
+ s = argv[ind];
+ if (*s != '-') {
+ break;
+ }
+ s++;
+ while ((c = *s++) != '\0') {
+ switch (c) {
+ case 'l':
+ case 'L':
+ if (*s == '\0') {
+ if (++ind >= argc) {
+ fprintf(stderr, "%s: error: no argument given to option '%c'\n", progname, c);
+ exit(1);
+ }
+ s = argv[ind];
+ }
+ switch (c) {
+ case 'l':
+ log_mode = strtol(s, 0, 0);
+ break;
+
+ case 'L':
+ log_name = s;
+ break;
+
+ default:
+ fprintf(stderr, "%s: error: illegal option '%c'\n", progname, c);
+ exit(1);
+ }
+ s = "";
+ break;
+
+ default:
+ fprintf(stderr, "%s: error: illegal option '%c'\n", progname, c);
+ exit(1);
+ }
+ }
+ }
+
+ /* Create log file */
+ if (log_name == 0) {
+ log_file = NULL;
+ }
+ else if (strcmp(log_name, "-") == 0) {
+ log_file = stderr;
+ }
+ else if ((log_file = fopen(log_name, "a")) == NULL) {
+ fprintf(stderr, "%s: error: cannot create log file %s\n", progname, log_name);
+ exit(1);
+ }
+
+#endif
+
+ if (discovery_start(discovery_default_master_notifier)) {
+ discovery_default_master_notifier();
+ }
+
+ /* Process events - must run on the initial thread since ptrace()
+ * returns ECHILD otherwise, thinking we are not the owner. */
+ run_event_loop();
+ return 0;
+}
diff --git a/mdep.c b/mdep.c
index 5b8b60e5..44c56554 100644
--- a/mdep.c
+++ b/mdep.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/mdep.h b/mdep.h
index 9c81440f..f395d591 100644
--- a/mdep.h
+++ b/mdep.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/memory.c b/memory.c
index 8e0c6f89..d45ec817 100644
--- a/memory.c
+++ b/memory.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/memory.h b/memory.h
index dec99332..ead75d24 100644
--- a/memory.h
+++ b/memory.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/myalloc.c b/myalloc.c
index df1e4bc5..89ecaf2c 100644
--- a/myalloc.c
+++ b/myalloc.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/myalloc.h b/myalloc.h
index 57ffce34..86f979ea 100644
--- a/myalloc.h
+++ b/myalloc.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/peer.c b/peer.c
index d4de2935..64989cff 100644
--- a/peer.c
+++ b/peer.c
@@ -1,257 +1,257 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Implements peer server management.
- */
-
-#if defined(_WRS_KERNEL)
-# include <vxWorks.h>
-#endif
-#include <stddef.h>
-#include <errno.h>
-#include <assert.h>
-#include "mdep.h"
-#include "tcf.h"
-#include "peer.h"
-#include "myalloc.h"
-#include "events.h"
-#include "trace.h"
-
-#define STALE_CHECK_TIME 20
-
-typedef struct PeerServerList {
- PeerServer *root;
- int ind;
- int max;
- struct {
- peer_server_listener fnp;
- void *arg;
- } * list;
-} PeerServerList;
-
-static PeerServerList peer_server_list;
-static int stale_timer_active = 0;
-
-static void notify_listeners(PeerServerList * pi, PeerServer * ps, int changeType) {
- int i;
-
- trace(LOG_DISCOVERY, "peer server change, id=%s, type=%d", ps->id, changeType);
- for (i = 0; i < pi->ind; i++) {
- pi->list[i].fnp(ps, changeType, pi->list[i].arg);
- }
-}
-
-static int is_same(PeerServer *a, PeerServer *b) {
- int i;
- int j;
-
- if (a->ind != b->ind) {
- return 0;
- }
- for (i = 0; i < a->ind; i++) {
- for (j = 0; j < b->ind; j++) {
- if (strcmp(a->list[i].name, b->list[j].name) == 0) {
- break;
- }
- }
- if (j >= b->ind) {
- /* Name from a not found in b */
- return 0;
- }
- if (strcmp(a->list[i].value, b->list[j].value) != 0) {
- return 0;
- }
- }
- return 1;
-}
-
-static void clear_stale_peers(void *x) {
- PeerServerList *pi = &peer_server_list;
- PeerServer **sp = &pi->root;
- PeerServer *s;
- time_t timenow = time(NULL);
- int keep_timer = 0;
-
- assert(is_dispatch_thread());
- while ((s = *sp) != NULL) {
- if (s->create_time != s->stale_time && s->stale_time <= timenow) {
- /* Delete stale entry */
- *sp = s->next;
- notify_listeners(pi, s, -1);
- peer_server_free(s);
- }
- else {
- if (s->create_time != s->stale_time) {
- keep_timer = 1;
- }
- sp = &s->next;
- }
- }
- if (keep_timer) {
- post_event_with_delay(clear_stale_peers, NULL, STALE_CHECK_TIME*1000*1000);
- }
- else {
- stale_timer_active = 0;
- }
-}
-
-PeerServer * peer_server_alloc(void) {
- PeerServer * s = loc_alloc_zero(sizeof *s);
-
- s->max = 1;
- s->list = loc_alloc(s->max * sizeof *s->list);
- return s;
-}
-
-void peer_server_addprop(PeerServer * s, char * name, char * value) {
- int i;
-
- if (strcmp(name, "ID") == 0) {
- loc_free(name);
- s->id = value;
- return;
- }
- for (i = 0; i < s->ind; i++) {
- if (strcmp(s->list[i].name, name) == 0) {
- loc_free(name);
- loc_free(s->list[i].value);
- s->list[i].value = value;
- return;
- }
- }
- if (s->ind == s->max) {
- s->max *= 2;
- s->list = loc_realloc(s->list, s->max * sizeof *s->list);
- }
- s->list[s->ind].name = name;
- s->list[s->ind].value = value;
- s->ind++;
-}
-
-char *peer_server_getprop(PeerServer * s, char * name, char * default_value) {
- int i;
-
- for (i = 0; i < s->ind; i++) {
- if (strcmp(s->list[i].name, name) == 0) {
- return s->list[i].value;
- }
- }
- return default_value;
-}
-
-void peer_server_free(PeerServer * s) {
- while (s->ind > 0) {
- s->ind--;
- loc_free(s->list[s->ind].name);
- loc_free(s->list[s->ind].value);
- }
- loc_free(s->list);
- if (s->id) loc_free(s->id);
- loc_free(s);
-}
-
-PeerServer * peer_server_add(PeerServer * n, unsigned int stale_delta) {
- PeerServerList *pi = &peer_server_list;
- PeerServer ** sp = &pi->root;
- PeerServer * s;
- int type = 1;
-
- assert(is_dispatch_thread());
- while ((s = *sp) != NULL) {
- if (strcmp(s->id, n->id) == 0) {
- if (s->flags & PS_FLAG_LOCAL && !(n->flags & PS_FLAG_LOCAL)) {
- /* Never replace local entries with discovered ones */
- peer_server_free(n);
- return s;
- }
- if (is_same(s, n)) {
- s->create_time = time(NULL);
- s->stale_time = s->create_time + stale_delta;
- s->flags = n->flags;
- peer_server_free(n);
- return s;
- }
- *sp = s->next;
- peer_server_free(s);
- type = 0;
- break;
- }
- sp = &s->next;
- }
- n->create_time = time(NULL);
- n->stale_time = n->create_time + stale_delta;
- n->next = pi->root;
- pi->root = n;
- notify_listeners(pi, n, type);
- if (!stale_timer_active && stale_delta != 0) {
- stale_timer_active = 1;
- post_event_with_delay(clear_stale_peers, NULL, STALE_CHECK_TIME*1000*1000);
- }
- return n;
-}
-
-void peer_server_remove(const char *id) {
- PeerServerList *pi = &peer_server_list;
- PeerServer ** sp = &pi->root;
- PeerServer * s;
-
- assert(is_dispatch_thread());
- while ((s = *sp) != NULL) {
- if (strcmp(s->id, id) == 0) {
- *sp = s->next;
- notify_listeners(pi, s, -1);
- peer_server_free(s);
- break;
- }
- sp = &s->next;
- }
-}
-
-int peer_server_iter(peer_server_iter_fnp fnp, void * arg) {
- PeerServerList * pi = &peer_server_list;
- PeerServer * s = pi->root;
- int rval;
-
- assert(is_dispatch_thread());
- while (s != NULL) {
- rval = fnp(s, arg);
- if (rval != 0) {
- /* Abort iteration */
- return rval;
- }
- s = s->next;
- }
- return 0;
-}
-
-void peer_server_add_listener(peer_server_listener fnp, void * arg) {
- PeerServerList * pi = &peer_server_list;
- int i;
-
- for (i = 0; i < pi->ind; i++) {
- if (pi->list[i].fnp == fnp && pi->list[i].arg == arg) {
- /* Already in the list */
- return;
- }
- }
- if (pi->max == 0) {
- pi->max = 1;
- pi->list = loc_alloc(pi->max * sizeof *pi->list);
- }
- else if (pi->ind == pi->max) {
- pi->max *= 2;
- pi->list = loc_realloc(pi->list, pi->max * sizeof *pi->list);
- }
- pi->list[pi->ind].fnp = fnp;
- pi->list[pi->ind].arg = arg;
- pi->ind++;
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Implements peer server management.
+ */
+
+#if defined(_WRS_KERNEL)
+# include <vxWorks.h>
+#endif
+#include <stddef.h>
+#include <errno.h>
+#include <assert.h>
+#include "mdep.h"
+#include "tcf.h"
+#include "peer.h"
+#include "myalloc.h"
+#include "events.h"
+#include "trace.h"
+
+#define STALE_CHECK_TIME 20
+
+typedef struct PeerServerList {
+ PeerServer *root;
+ int ind;
+ int max;
+ struct {
+ peer_server_listener fnp;
+ void *arg;
+ } * list;
+} PeerServerList;
+
+static PeerServerList peer_server_list;
+static int stale_timer_active = 0;
+
+static void notify_listeners(PeerServerList * pi, PeerServer * ps, int changeType) {
+ int i;
+
+ trace(LOG_DISCOVERY, "peer server change, id=%s, type=%d", ps->id, changeType);
+ for (i = 0; i < pi->ind; i++) {
+ pi->list[i].fnp(ps, changeType, pi->list[i].arg);
+ }
+}
+
+static int is_same(PeerServer *a, PeerServer *b) {
+ int i;
+ int j;
+
+ if (a->ind != b->ind) {
+ return 0;
+ }
+ for (i = 0; i < a->ind; i++) {
+ for (j = 0; j < b->ind; j++) {
+ if (strcmp(a->list[i].name, b->list[j].name) == 0) {
+ break;
+ }
+ }
+ if (j >= b->ind) {
+ /* Name from a not found in b */
+ return 0;
+ }
+ if (strcmp(a->list[i].value, b->list[j].value) != 0) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void clear_stale_peers(void *x) {
+ PeerServerList *pi = &peer_server_list;
+ PeerServer **sp = &pi->root;
+ PeerServer *s;
+ time_t timenow = time(NULL);
+ int keep_timer = 0;
+
+ assert(is_dispatch_thread());
+ while ((s = *sp) != NULL) {
+ if (s->create_time != s->stale_time && s->stale_time <= timenow) {
+ /* Delete stale entry */
+ *sp = s->next;
+ notify_listeners(pi, s, -1);
+ peer_server_free(s);
+ }
+ else {
+ if (s->create_time != s->stale_time) {
+ keep_timer = 1;
+ }
+ sp = &s->next;
+ }
+ }
+ if (keep_timer) {
+ post_event_with_delay(clear_stale_peers, NULL, STALE_CHECK_TIME*1000*1000);
+ }
+ else {
+ stale_timer_active = 0;
+ }
+}
+
+PeerServer * peer_server_alloc(void) {
+ PeerServer * s = loc_alloc_zero(sizeof *s);
+
+ s->max = 1;
+ s->list = loc_alloc(s->max * sizeof *s->list);
+ return s;
+}
+
+void peer_server_addprop(PeerServer * s, char * name, char * value) {
+ int i;
+
+ if (strcmp(name, "ID") == 0) {
+ loc_free(name);
+ s->id = value;
+ return;
+ }
+ for (i = 0; i < s->ind; i++) {
+ if (strcmp(s->list[i].name, name) == 0) {
+ loc_free(name);
+ loc_free(s->list[i].value);
+ s->list[i].value = value;
+ return;
+ }
+ }
+ if (s->ind == s->max) {
+ s->max *= 2;
+ s->list = loc_realloc(s->list, s->max * sizeof *s->list);
+ }
+ s->list[s->ind].name = name;
+ s->list[s->ind].value = value;
+ s->ind++;
+}
+
+char *peer_server_getprop(PeerServer * s, char * name, char * default_value) {
+ int i;
+
+ for (i = 0; i < s->ind; i++) {
+ if (strcmp(s->list[i].name, name) == 0) {
+ return s->list[i].value;
+ }
+ }
+ return default_value;
+}
+
+void peer_server_free(PeerServer * s) {
+ while (s->ind > 0) {
+ s->ind--;
+ loc_free(s->list[s->ind].name);
+ loc_free(s->list[s->ind].value);
+ }
+ loc_free(s->list);
+ if (s->id) loc_free(s->id);
+ loc_free(s);
+}
+
+PeerServer * peer_server_add(PeerServer * n, unsigned int stale_delta) {
+ PeerServerList *pi = &peer_server_list;
+ PeerServer ** sp = &pi->root;
+ PeerServer * s;
+ int type = 1;
+
+ assert(is_dispatch_thread());
+ while ((s = *sp) != NULL) {
+ if (strcmp(s->id, n->id) == 0) {
+ if (s->flags & PS_FLAG_LOCAL && !(n->flags & PS_FLAG_LOCAL)) {
+ /* Never replace local entries with discovered ones */
+ peer_server_free(n);
+ return s;
+ }
+ if (is_same(s, n)) {
+ s->create_time = time(NULL);
+ s->stale_time = s->create_time + stale_delta;
+ s->flags = n->flags;
+ peer_server_free(n);
+ return s;
+ }
+ *sp = s->next;
+ peer_server_free(s);
+ type = 0;
+ break;
+ }
+ sp = &s->next;
+ }
+ n->create_time = time(NULL);
+ n->stale_time = n->create_time + stale_delta;
+ n->next = pi->root;
+ pi->root = n;
+ notify_listeners(pi, n, type);
+ if (!stale_timer_active && stale_delta != 0) {
+ stale_timer_active = 1;
+ post_event_with_delay(clear_stale_peers, NULL, STALE_CHECK_TIME*1000*1000);
+ }
+ return n;
+}
+
+void peer_server_remove(const char *id) {
+ PeerServerList *pi = &peer_server_list;
+ PeerServer ** sp = &pi->root;
+ PeerServer * s;
+
+ assert(is_dispatch_thread());
+ while ((s = *sp) != NULL) {
+ if (strcmp(s->id, id) == 0) {
+ *sp = s->next;
+ notify_listeners(pi, s, -1);
+ peer_server_free(s);
+ break;
+ }
+ sp = &s->next;
+ }
+}
+
+int peer_server_iter(peer_server_iter_fnp fnp, void * arg) {
+ PeerServerList * pi = &peer_server_list;
+ PeerServer * s = pi->root;
+ int rval;
+
+ assert(is_dispatch_thread());
+ while (s != NULL) {
+ rval = fnp(s, arg);
+ if (rval != 0) {
+ /* Abort iteration */
+ return rval;
+ }
+ s = s->next;
+ }
+ return 0;
+}
+
+void peer_server_add_listener(peer_server_listener fnp, void * arg) {
+ PeerServerList * pi = &peer_server_list;
+ int i;
+
+ for (i = 0; i < pi->ind; i++) {
+ if (pi->list[i].fnp == fnp && pi->list[i].arg == arg) {
+ /* Already in the list */
+ return;
+ }
+ }
+ if (pi->max == 0) {
+ pi->max = 1;
+ pi->list = loc_alloc(pi->max * sizeof *pi->list);
+ }
+ else if (pi->ind == pi->max) {
+ pi->max *= 2;
+ pi->list = loc_realloc(pi->list, pi->max * sizeof *pi->list);
+ }
+ pi->list[pi->ind].fnp = fnp;
+ pi->list[pi->ind].arg = arg;
+ pi->ind++;
+}
diff --git a/peer.h b/peer.h
index f93fd747..eef9dc0b 100644
--- a/peer.h
+++ b/peer.h
@@ -1,72 +1,72 @@
-/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-
-/*
- * Peer server management interface
- */
-
-#ifndef D_peer
-#define D_peer
-
-#include <stdlib.h>
-#include <time.h>
-
-typedef struct PeerServer PeerServer;
-
-struct PeerServer {
- char * id;
- int max;
- int ind;
- struct {
- char * name;
- char * value;
- } * list;
- unsigned int flags;
- time_t create_time;
- time_t stale_time;
- PeerServer * next;
-};
-
-enum {
- PS_FLAG_LOCAL = 1,
- PS_FLAG_PRIVATE = PS_FLAG_LOCAL*2,
- PS_FLAG_DISCOVERABLE = PS_FLAG_PRIVATE*2
-};
-
-/* Allocate peer server object */
-extern PeerServer * peer_server_alloc(void);
-
-/* Add properties to peer server object */
-extern void peer_server_addprop(PeerServer * ps, char * name, char * value);
-
-/* Add properties to peer server object */
-extern char * peer_server_getprop(PeerServer * ps, char * name, char * default_value);
-
-/* Free peer server object */
-extern void peer_server_free(PeerServer * ps);
-
-/* Add peer server information */
-extern PeerServer * peer_server_add(PeerServer * ps, unsigned int stale_delta);
-
-/* Remove peer server information */
-extern void peer_server_remove(const char *id);
-
-typedef int (*peer_server_iter_fnp)(PeerServer * ps, void * client_data);
-
-/* Iterate over all peer servers */
-extern int peer_server_iter(peer_server_iter_fnp fnp, void * client_data);
-
-typedef void (*peer_server_listener)(PeerServer *ps, int changeType, void * client_data);
-
-/* Peer server list change listener */
-extern void peer_server_add_listener(peer_server_listener listener, void * client_data);
-
-#endif
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Peer server management interface
+ */
+
+#ifndef D_peer
+#define D_peer
+
+#include <stdlib.h>
+#include <time.h>
+
+typedef struct PeerServer PeerServer;
+
+struct PeerServer {
+ char * id;
+ int max;
+ int ind;
+ struct {
+ char * name;
+ char * value;
+ } * list;
+ unsigned int flags;
+ time_t create_time;
+ time_t stale_time;
+ PeerServer * next;
+};
+
+enum {
+ PS_FLAG_LOCAL = 1,
+ PS_FLAG_PRIVATE = PS_FLAG_LOCAL*2,
+ PS_FLAG_DISCOVERABLE = PS_FLAG_PRIVATE*2
+};
+
+/* Allocate peer server object */
+extern PeerServer * peer_server_alloc(void);
+
+/* Add properties to peer server object */
+extern void peer_server_addprop(PeerServer * ps, char * name, char * value);
+
+/* Add properties to peer server object */
+extern char * peer_server_getprop(PeerServer * ps, char * name, char * default_value);
+
+/* Free peer server object */
+extern void peer_server_free(PeerServer * ps);
+
+/* Add peer server information */
+extern PeerServer * peer_server_add(PeerServer * ps, unsigned int stale_delta);
+
+/* Remove peer server information */
+extern void peer_server_remove(const char *id);
+
+typedef int (*peer_server_iter_fnp)(PeerServer * ps, void * client_data);
+
+/* Iterate over all peer servers */
+extern int peer_server_iter(peer_server_iter_fnp fnp, void * client_data);
+
+typedef void (*peer_server_listener)(PeerServer *ps, int changeType, void * client_data);
+
+/* Peer server list change listener */
+extern void peer_server_add_listener(peer_server_listener listener, void * client_data);
+
+#endif
diff --git a/processes.c b/processes.c
index e2001f07..18f6040c 100644
--- a/processes.c
+++ b/processes.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/processes.h b/processes.h
index 88912ae4..6b5f04f3 100644
--- a/processes.h
+++ b/processes.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/protocol.c b/protocol.c
index 85e93277..dd3cf21b 100644
--- a/protocol.c
+++ b/protocol.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/protocol.h b/protocol.h
index 74f30dbe..92aef9f5 100644
--- a/protocol.h
+++ b/protocol.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/proxy.c b/proxy.c
index ad244778..f8843066 100644
--- a/proxy.c
+++ b/proxy.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/proxy.h b/proxy.h
index 208b5fde..24eef2ee 100644
--- a/proxy.h
+++ b/proxy.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/registers.c b/registers.c
index 2979797c..8813cfc1 100644
--- a/registers.c
+++ b/registers.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/registers.h b/registers.h
index c0a33434..3b40fe91 100644
--- a/registers.h
+++ b/registers.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/runctrl.c b/runctrl.c
index e525091a..a3310d98 100644
--- a/runctrl.c
+++ b/runctrl.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/runctrl.h b/runctrl.h
index bf6f61eb..d70fafc8 100644
--- a/runctrl.h
+++ b/runctrl.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/stacktrace.c b/stacktrace.c
index 9c29b3a0..b452ae57 100644
--- a/stacktrace.c
+++ b/stacktrace.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/stacktrace.h b/stacktrace.h
index b2bad852..5e039bad 100644
--- a/stacktrace.h
+++ b/stacktrace.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/streams.c b/streams.c
index 86fe4070..15b3d0a2 100644
--- a/streams.c
+++ b/streams.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/streams.h b/streams.h
index e15e62e7..775b63a0 100644
--- a/streams.h
+++ b/streams.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/symbols.c b/symbols.c
index b36cf04b..bcbe6602 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/symbols.h b/symbols.h
index e8d1bf93..7c2d05ac 100644
--- a/symbols.h
+++ b/symbols.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/sysmon.c b/sysmon.c
index f0083a77..47d41c1d 100644
--- a/sysmon.c
+++ b/sysmon.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/sysmon.h b/sysmon.h
index a29b9999..e8d535b1 100644
--- a/sysmon.h
+++ b/sysmon.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/tcf.h b/tcf.h
index 034ea3e3..a936fcb9 100644
--- a/tcf.h
+++ b/tcf.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/test.c b/test.c
index 885e813f..1cb3d6ce 100644
--- a/test.c
+++ b/test.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/test.h b/test.h
index 6baec28f..279ce3f5 100644
--- a/test.h
+++ b/test.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/trace.c b/trace.c
index dffa79ec..d0ee1fec 100644
--- a/trace.c
+++ b/trace.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
diff --git a/trace.h b/trace.h
index f996103e..e6088119 100644
--- a/trace.h
+++ b/trace.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at

Back to the top