diff options
-rw-r--r-- | base64.c | 2 | ||||
-rw-r--r-- | base64.h | 2 | ||||
-rw-r--r-- | breakpoints.c | 2 | ||||
-rw-r--r-- | breakpoints.h | 2 | ||||
-rw-r--r-- | channel.c | 2 | ||||
-rw-r--r-- | channel.h | 2 | ||||
-rw-r--r-- | channel_tcp.c | 1488 | ||||
-rw-r--r-- | channel_tcp.h | 62 | ||||
-rw-r--r-- | cmdline.c | 2 | ||||
-rw-r--r-- | cmdline.h | 2 | ||||
-rw-r--r-- | config.h | 2 | ||||
-rw-r--r-- | context.c | 2 | ||||
-rw-r--r-- | context.h | 2 | ||||
-rw-r--r-- | diagnostics.c | 2 | ||||
-rw-r--r-- | diagnostics.h | 2 | ||||
-rw-r--r-- | discovery.c | 526 | ||||
-rw-r--r-- | discovery.h | 112 | ||||
-rw-r--r-- | discovery_help.c | 212 | ||||
-rw-r--r-- | discovery_help.h | 50 | ||||
-rw-r--r-- | discovery_udp.c | 826 | ||||
-rw-r--r-- | discovery_udp.h | 48 | ||||
-rw-r--r-- | dwarf.h | 2 | ||||
-rw-r--r-- | dwarfio.c | 2 | ||||
-rw-r--r-- | dwarfio.h | 2 | ||||
-rw-r--r-- | elf.c | 2 | ||||
-rw-r--r-- | elf.h | 2 | ||||
-rw-r--r-- | errors.c | 2 | ||||
-rw-r--r-- | errors.h | 2 | ||||
-rw-r--r-- | events.c | 2 | ||||
-rw-r--r-- | events.h | 2 | ||||
-rw-r--r-- | exceptions.c | 2 | ||||
-rw-r--r-- | exceptions.h | 2 | ||||
-rw-r--r-- | expressions.c | 2 | ||||
-rw-r--r-- | expressions.h | 2 | ||||
-rw-r--r-- | filesystem.c | 2 | ||||
-rw-r--r-- | filesystem.h | 2 | ||||
-rw-r--r-- | ip_ifc.c | 182 | ||||
-rw-r--r-- | ip_ifc.h | 60 | ||||
-rw-r--r-- | json.c | 2 | ||||
-rw-r--r-- | json.h | 2 | ||||
-rw-r--r-- | linenumbers.c | 2 | ||||
-rw-r--r-- | linenumbers.h | 2 | ||||
-rw-r--r-- | link.h | 2 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | main_client.c | 258 | ||||
-rw-r--r-- | main_reg.c | 252 | ||||
-rw-r--r-- | mdep.c | 2 | ||||
-rw-r--r-- | mdep.h | 2 | ||||
-rw-r--r-- | memory.c | 2 | ||||
-rw-r--r-- | memory.h | 2 | ||||
-rw-r--r-- | myalloc.c | 2 | ||||
-rw-r--r-- | myalloc.h | 2 | ||||
-rw-r--r-- | peer.c | 514 | ||||
-rw-r--r-- | peer.h | 144 | ||||
-rw-r--r-- | processes.c | 2 | ||||
-rw-r--r-- | processes.h | 2 | ||||
-rw-r--r-- | protocol.c | 2 | ||||
-rw-r--r-- | protocol.h | 2 | ||||
-rw-r--r-- | proxy.c | 2 | ||||
-rw-r--r-- | proxy.h | 2 | ||||
-rw-r--r-- | registers.c | 2 | ||||
-rw-r--r-- | registers.h | 2 | ||||
-rw-r--r-- | runctrl.c | 2 | ||||
-rw-r--r-- | runctrl.h | 2 | ||||
-rw-r--r-- | stacktrace.c | 2 | ||||
-rw-r--r-- | stacktrace.h | 2 | ||||
-rw-r--r-- | streams.c | 2 | ||||
-rw-r--r-- | streams.h | 2 | ||||
-rw-r--r-- | symbols.c | 2 | ||||
-rw-r--r-- | symbols.h | 2 | ||||
-rw-r--r-- | sysmon.c | 2 | ||||
-rw-r--r-- | sysmon.h | 2 | ||||
-rw-r--r-- | tcf.h | 2 | ||||
-rw-r--r-- | test.c | 2 | ||||
-rw-r--r-- | test.h | 2 | ||||
-rw-r--r-- | trace.c | 2 | ||||
-rw-r--r-- | trace.h | 2 |
77 files changed, 2430 insertions, 2430 deletions
@@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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; +} @@ -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 @@ -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 @@ -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 @@ -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 @@ -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; +} @@ -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; +} @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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++; +} @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 |