30static size_t MAX_SIZE_T = (size_t)(-1);
32#ifdef VRPN_USE_WINSOCK_SOCKETS
35#define vrpn_closeSocket closesocket
39#define vrpn_socket_error WSAGetLastError()
40static std::string WSA_number_to_string(
int err)
43 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
44 FORMAT_MESSAGE_IGNORE_INSERTS,
45 NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
51#define vrpn_socket_error_to_chars(x) (WSA_number_to_string(x)).c_str()
52#define vrpn_EINTR WSAEINTR
57#define vrpn_closeSocket close
59#define vrpn_socket_error errno
60#define vrpn_socket_error_to_chars(x) strerror(x)
61#define vrpn_EINTR EINTR
64#include <netinet/in.h>
65#include <sys/socket.h>
85#include <arpa/nameser.h>
89#ifndef VRPN_USE_WINSOCK_SOCKETS
92#include <netinet/tcp.h>
97#ifdef VRPN_USE_WINSOCK_SOCKETS
98#define SOCK_CAST (char *)
101#define SOCK_CAST (const char *)
107#if defined(_AIX) || defined(__APPLE__) || defined(ANDROID) || defined(__linux)
108#define GSN_CAST (socklen_t *)
111#define GSN_CAST (unsigned int *)
121int gethostname(
char *,
int);
135#ifndef VRPN_USE_WINSOCK_SOCKETS
136#define INVALID_SOCKET -1
141#pragma warning(disable : 4127)
217 "VRPN_Connection_Dropped_Last_Connection";
225#define getdtablesize() MAXFUPLIM
229#define getdtablesize() MAXFUPLIM
238#define RSH "/usr/bin/ssh"
240#define RSH "/usr/bin/rsh"
245#define UDP_CALL_TIMEOUT (2)
246#define UDP_CALL_RETRIES (5)
252#define SERVCOUNT (20)
253#define SERVWAIT (120 / SERVCOUNT)
258#define vrpn_CONNECTION_MAX_XLATION_TABLE_SIZE 2000
306struct cRemoteMapping {
308 vrpn_int32 remote_id;
312class vrpn_TranslationTable {
316 ~vrpn_TranslationTable(
void);
320 vrpn_int32 numEntries(
void)
const;
321 vrpn_int32 mapToLocalID(vrpn_int32 remote_id)
const;
328 vrpn_int32 addRemoteEntry(
vrpn_CNAME name, vrpn_int32 remote_id,
329 vrpn_int32 local_id);
334 vrpn_bool addLocalID(
const char *name, vrpn_int32 local_id);
339 vrpn_int32 d_numEntries;
343vrpn_TranslationTable::vrpn_TranslationTable(
void)
349 d_entry[i].name = NULL;
350 d_entry[i].remote_id = -1;
351 d_entry[i].local_id = -1;
355vrpn_TranslationTable::~vrpn_TranslationTable(
void) { clear(); }
357vrpn_int32 vrpn_TranslationTable::numEntries(
void)
const
362vrpn_int32 vrpn_TranslationTable::mapToLocalID(vrpn_int32 remote_id)
const
364 if ((remote_id < 0) || (remote_id > d_numEntries)) {
368 fprintf(stderr,
"vrpn_TranslationTable::mapToLocalID: "
369 "Remote ID %d is illegal!\n",
377 fprintf(stderr,
"Remote ID %d maps to local ID %d (%s).\n", remote_id,
378 d_entry[remote_id].local_id, d_entry[remote_id].name);
381 return d_entry[remote_id].local_id;
384vrpn_int32 vrpn_TranslationTable::addRemoteEntry(
vrpn_CNAME name,
385 vrpn_int32 remote_id,
390 useEntry = remote_id;
393 fprintf(stderr,
"vrpn_TranslationTable::addRemoteEntry: "
394 "Too many entries in table (%d).\n",
405 if (!d_entry[useEntry].name) {
406 try { d_entry[useEntry].name =
new char[
sizeof(
vrpn_CNAME)]; }
408 fprintf(stderr,
"vrpn_TranslationTable::addRemoteEntry: "
414 memcpy(d_entry[useEntry].name, name,
sizeof(
vrpn_CNAME));
415 d_entry[useEntry].remote_id = remote_id;
416 d_entry[useEntry].local_id = local_id;
419 fprintf(stderr,
"Set up remote ID %d named %s with local equivalent %d.\n",
420 remote_id, name, local_id);
423 if (d_numEntries <= useEntry) {
424 d_numEntries = useEntry + 1;
430vrpn_bool vrpn_TranslationTable::addLocalID(
const char *name,
435 for (i = 0; i < d_numEntries; i++) {
436 if (d_entry[i].name && !strcmp(d_entry[i].name, name)) {
437 d_entry[i].local_id = local_id;
444void vrpn_TranslationTable::clear(
void)
448 for (i = 0; i < d_numEntries; i++) {
449 if (d_entry[i].name) {
451 delete[] d_entry[i].name;
453 fprintf(stderr,
"vrpn_TranslationTable::clear: delete failed\n");
456 d_entry[i].name = NULL;
458 d_entry[i].local_id = -1;
459 d_entry[i].remote_id = -1;
485 fprintf(stderr,
"vrpn_Log: Out of memory.\n");
504 fprintf(stderr,
"vrpn_Log::~vrpn_Log: delete failed\n");
515 fprintf(stderr,
"vrpn_Log::~vrpn_Log: delete failed\n");
539 fprintf(stderr,
"vrpn_Log::open: Log file has no name.\n");
543 fprintf(stderr,
"vrpn_Log::open: Log file is already open.\n");
551 fprintf(stderr,
"vrpn_Log::open: "
552 "Log file \"%s\" already exists.\n",
560 fprintf(stderr,
"vrpn_Log::open: "
561 "Couldn't open log file \"%s\": ",
569 d_file = fopen(
"/tmp/vrpn_emergency_log",
"r");
573 perror(
"vrpn_Log::open_log: "
574 "Emergency log file \"/tmp/vrpn_emergency_log\" "
575 "already exists.\n");
578 d_file = fopen(
"/tmp/vrpn_emergency_log",
"wb");
580 perror(
"vrpn_Log::open: "
581 "Couldn't open emergency log file "
582 "\"/tmp/vrpn_emergency_log\": ");
590 fprintf(stderr,
"Writing to /tmp/vrpn_emergency_log instead.\n");
599 int final_retval = 0;
603 fprintf(stderr,
"vrpn_Log::close: "
604 "close of log file failed!\n");
613 fprintf(stderr,
"vrpn_Log::close: delete failed\n");
626 int final_retval = 0;
634 fprintf(stderr,
"vrpn_Log::saveLogSoFar: "
635 "Log file is not open!\n");
656 fprintf(stderr,
"vrpn_Log::saveLogSoFar: "
657 "Couldn't write magic cookie to log file "
658 "(got %d, expected %d).\n",
659 static_cast<int>(retval),
679 vrpn_int32 values[6];
681 memcpy(&(values[0]), &lp->
data.
type,
sizeof(vrpn_int32));
682 memcpy(&(values[1]), &lp->
data.
sender,
sizeof(vrpn_int32));
683 memcpy(&(values[2]), &lp->
data.
msg_time.tv_sec,
sizeof(vrpn_int32));
684 memcpy(&(values[3]), &lp->
data.
msg_time.tv_usec,
sizeof(vrpn_int32));
686 memcpy(&(values[5]), &zero,
sizeof(vrpn_int32));
687 retval = fwrite(values,
sizeof(vrpn_int32), 6,
d_file);
691 "vrpn_Log::saveLogSoFar: "
692 "Couldn't write log file (got %d, expected %lud).\n",
693 static_cast<int>(retval),
694 static_cast<unsigned long>(
sizeof(lp->
data)));
707 if (retval !=
static_cast<size_t>(host_len)) {
708 fprintf(stderr,
"vrpn_Log::saveLogSoFar: "
709 "Couldn't write log file.\n");
723 fprintf(stderr,
"vrpn_Log::saveLogSoFar: delete failed\n");
730 fprintf(stderr,
"vrpn_Log::saveLogSoFar: delete failed\n");
742 vrpn_int32 type, vrpn_int32 sender,
752 return logMessage(
static_cast<vrpn_int32
>(payloadLen), time, type,
753 sender, buffer, vrpn_TRUE);
761 vrpn_int32 type, vrpn_int32 sender,
766 return logMessage(payloadLen, time, type, sender, buffer);
773 vrpn_int32 type, vrpn_int32 sender,
const char *buffer,
777 vrpn_int32 effectiveType;
778 vrpn_int32 effectiveSender;
781 effectiveType =
d_types->mapToLocalID(type);
782 effectiveSender =
d_senders->mapToLocalID(sender);
785 effectiveType = type;
786 effectiveSender = sender;
791 if (
checkFilters(payloadLen, time, effectiveType, effectiveSender,
802 fprintf(stderr,
"vrpn_Log::logMessage: "
818 if (payloadLen > 0) {
819 try { lp->
data.
buffer =
new char[payloadLen]; }
821 fprintf(stderr,
"vrpn_Log::logMessage: "
827 memcpy(
const_cast<char *
>(lp->
data.
buffer), buffer, payloadLen);
851 newName.
assign(strlen(name) + 100 + 1, 0);
858 dot = strrchr(name,
'.');
860 strncpy(newName.
data(), name, dot - name);
863 strncpy(newName.
data(), name, newName.
size());
865 len = strlen(newName.
data());
866 snprintf(newName.
data() + len, newName.
size() - len,
"-%d", index);
868 strncat(newName.
data(), dot, newName.
size() - (strlen(newName.
data())+1) );
882 fprintf(stderr,
"vrpn_Log::setName: delete failed\n");
903 fprintf(stderr,
"vrpn_Log::setCookie: delete failed\n");
909 fprintf(stderr,
"vrpn_Log::setCookie: Out of memory.\n");
926 fprintf(stderr,
"vrpn_Log::addFilter: Out of memory.\n");
930 newEntry->
filter = filter;
941 vrpn_int32 type, vrpn_int32 sender,
971class vrpn_TypeDispatcher {
975 ~vrpn_TypeDispatcher(
void);
979 int numTypes(
void)
const;
980 const char *typeName(
int which)
const;
982 vrpn_int32 getTypeID(
const char *name);
985 int numSenders(
void)
const;
986 const char *senderName(
int which)
const;
988 vrpn_int32 getSenderID(
const char *name);
993 vrpn_int32 addType(
const char *name);
994 vrpn_int32 addSender(
const char *name);
996 vrpn_int32 registerType(
const char *name);
1001 vrpn_int32 registerSender(
const char *name);
1009 void *userdata, vrpn_int32 sender);
1016 int doCallbacksFor(vrpn_int32 type, vrpn_int32 sender, timeval time,
1017 vrpn_uint32 len,
const char *buffer);
1018 int doSystemCallbacksFor(vrpn_int32 type, vrpn_int32 sender, timeval time,
1019 vrpn_uint32 len,
const char *buffer,
1026 struct vrpnLocalMapping {
1040 vrpnMsgCallbackEntry *d_genericCallbacks;
1043vrpn_TypeDispatcher::vrpn_TypeDispatcher(
void)
1046 , d_genericCallbacks(NULL)
1058vrpn_TypeDispatcher::~vrpn_TypeDispatcher(
void)
1060 vrpnMsgCallbackEntry *pVMCB, *pVMCB_Del;
1063 for (i = 0; i < d_numTypes; i++) {
1064 pVMCB = d_types[i].who_cares;
1067 pVMCB = pVMCB_Del->
next;
1071 fprintf(stderr,
"vrpn_TypeDispatcher::~vrpn_TypeDispatcher: delete failed\n");
1077 pVMCB = d_genericCallbacks;
1081 pVMCB = pVMCB_Del->
next;
1085 fprintf(stderr,
"vrpn_TypeDispatcher::~vrpn_TypeDispatcher: delete failed\n");
1094int vrpn_TypeDispatcher::numTypes(
void)
const {
return d_numTypes; }
1096const char *vrpn_TypeDispatcher::typeName(
int i)
const
1098 if ((i < 0) || (i >= d_numTypes)) {
1101 return d_types[i].name;
1104vrpn_int32 vrpn_TypeDispatcher::getTypeID(
const char *name)
1108 for (i = 0; i < d_numTypes; i++) {
1109 if (!strcmp(name, d_types[i].name)) {
1117int vrpn_TypeDispatcher::numSenders(
void)
const {
return d_numSenders; }
1119const char *vrpn_TypeDispatcher::senderName(
int i)
const
1121 if ((i < 0) || (i >= d_numSenders)) {
1124 return d_senders[i];
1127vrpn_int32 vrpn_TypeDispatcher::getSenderID(
const char *name)
1131 for (i = 0; i < d_numSenders; i++) {
1132 if (!strcmp(name, d_senders[i])) {
1140vrpn_int32 vrpn_TypeDispatcher::addType(
const char *name)
1145 fprintf(stderr,
"vrpn_TypeDispatcher::addType: "
1153 d_types[d_numTypes].who_cares = NULL;
1154 d_types[d_numTypes].cCares = 0;
1157 return d_numTypes - 1;
1160vrpn_int32 vrpn_TypeDispatcher::addSender(
const char *name)
1165 fprintf(stderr,
"vrpn_TypeDispatcher::addSender: "
1166 "Too many! (%d).\n",
1171 if (!d_senders[d_numSenders]) {
1175 try { d_senders[d_numSenders] =
new char[
sizeof(
vrpn_CNAME)]; }
1177 fprintf(stderr,
"vrpn_TypeDispatcher::addSender: "
1178 "Can't allocate memory for new record\n");
1184 strncpy(d_senders[d_numSenders], name,
sizeof(
vrpn_CNAME) - 1);
1185 d_senders[d_numSenders][
sizeof(
vrpn_CNAME) - 1] =
'\0';
1189 return d_numSenders - 1;
1192vrpn_int32 vrpn_TypeDispatcher::registerType(
const char *name)
1197 retval = getTypeID(name);
1202 return addType(name);
1205vrpn_int32 vrpn_TypeDispatcher::registerSender(
const char *name)
1210 retval = getSenderID(name);
1215 return addSender(name);
1218int vrpn_TypeDispatcher::addHandler(vrpn_int32 type,
1222 vrpnMsgCallbackEntry *new_entry;
1223 vrpnMsgCallbackEntry **ptr;
1227 if (((type < 0) || (type >= d_numTypes)) && (type !=
vrpn_ANY_TYPE)) {
1228 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: No such type\n");
1234 ((sender < 0) || (sender >= d_numSenders))) {
1235 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: No such sender\n");
1240 if (handler == NULL) {
1241 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: NULL handler\n");
1247 new_entry =
new vrpnMsgCallbackEntry;
1250 new_entry->
sender = sender;
1252 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: Out of memory\n");
1257 printf(
"Adding user handler for type %ld, sender %ld\n", type, sender);
1266 ptr = &d_genericCallbacks;
1269 ptr = &d_types[type].who_cares;
1273 ptr = &((*ptr)->next);
1276 new_entry->
next = NULL;
1281int vrpn_TypeDispatcher::removeHandler(vrpn_int32 type,
1283 void *userdata, vrpn_int32 sender)
1286 vrpnMsgCallbackEntry *victim, **snitch;
1290 if (((type < 0) || (type >= d_numTypes)) && (type !=
vrpn_ANY_TYPE)) {
1291 fprintf(stderr,
"vrpn_TypeDispatcher::removeHandler: No such type\n");
1298 snitch = &d_genericCallbacks;
1301 snitch = &(d_types[type].who_cares);
1304 while ((victim != NULL) &&
1306 (victim->
sender != sender))) {
1307 snitch = &((*snitch)->next);
1308 victim = victim->
next;
1312 if (victim == NULL) {
1314 "vrpn_TypeDispatcher::removeHandler: No such handler\n");
1319 *snitch = victim->
next;
1323 fprintf(stderr,
"vrpn_TypeDispatcher::removeHandler: delete failed\n");
1330void vrpn_TypeDispatcher::setSystemHandler(vrpn_int32 type,
1333 d_systemMessages[-type] = handler;
1336int vrpn_TypeDispatcher::doCallbacksFor(vrpn_int32 type, vrpn_int32 sender,
1337 timeval time, vrpn_uint32 len,
1340 vrpnMsgCallbackEntry *who;
1341 vrpn_HANDLERPARAM p;
1348 if (type >= d_numTypes) {
1360 who = d_genericCallbacks;
1366 fprintf(stderr,
"vrpn_TypeDispatcher::doCallbacksFor: "
1367 "Nonzero user generic handler return.\n");
1377 who = d_types[type].who_cares;
1382 fprintf(stderr,
"vrpn_TypeDispatcher::doCallbacksFor: "
1383 "Nonzero user handler return.\n");
1395int vrpn_TypeDispatcher::doSystemCallbacksFor(vrpn_int32 type,
1396 vrpn_int32 sender, timeval time,
1401 vrpn_HANDLERPARAM p;
1407 fprintf(stderr,
"vrpn_TypeDispatcher::doSystemCallbacksFor: "
1408 "Illegal type %d.\n",
1413 if (!d_systemMessages[-type]) {
1424 return doSystemCallbacksFor(p, userdata);
1436 fprintf(stderr,
"vrpn_TypeDispatcher::doSystemCallbacksFor: "
1437 "Illegal type %d.\n",
1442 if (!d_systemMessages[-p.
type]) {
1446 retval = d_systemMessages[-p.
type](userdata, p);
1448 fprintf(stderr,
"vrpn_TypeDispatcher::doSystemCallbacksFor: "
1449 "Nonzero system handler return.\n");
1455void vrpn_TypeDispatcher::clear(
void)
1460 d_types[i].who_cares = NULL;
1461 d_types[i].cCares = 0;
1463 d_systemMessages[i] = NULL;
1467 if (d_senders[i] != NULL) {
1469 delete[] d_senders[i];
1471 fprintf(stderr,
"vrpn_TypeDispatcher::clear: delete failed\n");
1475 d_senders[i] = NULL;
1494 fprintf(stderr,
"vrpn_ConnectionManager::~vrpn_ConnectionManager: delete failed\n");
1499 while (d_anonList) {
1505 fprintf(stderr,
"vrpn_ConnectionManager::~vrpn_ConnectionManager: delete failed\n");
1521 static vrpn_ConnectionManager manager;
1531 p =
new knownConnection;
1541 p->next = d_anonList;
1557 knownConnection **snitch)
1561 knownConnection *victim = *snitch;
1563 while (victim && (victim->connection != c)) {
1564 snitch = &((*snitch)->next);
1572 *snitch = victim->next;
1576 fprintf(stderr,
"vrpn_ConnectionManager::deleteConnection: delete failed\n");
1587 for (p = d_kcList; p && strcmp(p->name, name); p = p->next) {
1593 return p->connection;
1596vrpn_ConnectionManager::vrpn_ConnectionManager(
void)
1614static int vrpn_getmyIP(
char *myIPchar,
unsigned maxlen,
1615 const char *NIC_IP = NULL,
1619 struct hostent *host;
1620 char myIPstring[100];
1622 if (myIPchar == NULL) {
1623 fprintf(stderr,
"vrpn_getmyIP: NULL pointer passed in\n");
1629 if (strlen(NIC_IP) > maxlen) {
1630 fprintf(stderr,
"vrpn_getmyIP: Name too long to return\n");
1634 fprintf(stderr,
"Was given IP address of %s so returning that.\n",
1637 strncpy(myIPchar, NIC_IP, maxlen);
1638 myIPchar[maxlen - 1] =
'\0';
1645 struct sockaddr_in socket_name;
1646 int socket_namelen =
sizeof(socket_name);
1648 if (getsockname(incoming_socket, (
struct sockaddr *)&socket_name,
1650 fprintf(stderr,
"vrpn_getmyIP: cannot get socket name.\n");
1654 snprintf(myIPstring, 100,
"%u.%u.%u.%u",
1655 ntohl(socket_name.sin_addr.s_addr) >> 24,
1656 (ntohl(socket_name.sin_addr.s_addr) >> 16) & 0xff,
1657 (ntohl(socket_name.sin_addr.s_addr) >> 8) & 0xff,
1658 ntohl(socket_name.sin_addr.s_addr) & 0xff);
1661 if ((
unsigned)strlen(myIPstring) > maxlen) {
1662 fprintf(stderr,
"vrpn_getmyIP: Name too long to return\n");
1669 fprintf(stderr,
"Decided on IP address of %s.\n", myIPchar);
1677 if (gethostname(myname,
sizeof(myname))) {
1678 fprintf(stderr,
"vrpn_getmyIP: Error finding local hostname\n");
1683 host = gethostbyname(myname);
1685 fprintf(stderr,
"vrpn_getmyIP: error finding host by name (%s)\n",
1692 if (host->h_length != 4) {
1693 fprintf(stderr,
"vrpn_getmyIP: Host length not 4\n");
1697 snprintf(myIPstring, 100,
"%u.%u.%u.%u",
1698 (
unsigned int)(
unsigned char)host->h_addr_list[0][0],
1699 (
unsigned int)(
unsigned char)host->h_addr_list[0][1],
1700 (
unsigned int)(
unsigned char)host->h_addr_list[0][2],
1701 (
unsigned int)(
unsigned char)host->h_addr_list[0][3]);
1704 if ((
unsigned)strlen(myIPstring) > maxlen) {
1705 fprintf(stderr,
"vrpn_getmyIP: Name too long to return\n");
1711 fprintf(stderr,
"Decided on IP address of %s.\n", myIPchar);
1723 fd_set *exceptfds,
struct timeval *timeout)
1725 fd_set tmpread, tmpwrite, tmpexcept;
1728 struct timeval timeout2;
1729 struct timeval *timeout2ptr;
1730 struct timeval start, stop, now;
1737 if ((timeout != NULL) &&
1738 ((timeout->tv_sec != 0) || (timeout->tv_usec != 0))) {
1739 timeout2 = *timeout;
1740 timeout2ptr = &timeout2;
1745 timeout2ptr = timeout;
1754 if (readfds != NULL) {
1760 if (writefds != NULL) {
1761 tmpwrite = *writefds;
1766 if (exceptfds != NULL) {
1767 tmpexcept = *exceptfds;
1770 FD_ZERO(&tmpexcept);
1774 ret = select(width, &tmpread, &tmpwrite, &tmpexcept, timeout2ptr);
1781 else if ((timeout != NULL) &&
1782 ((timeout->tv_sec != 0) || (timeout->tv_usec != 0))) {
1790 unsigned long usec_left;
1791 usec_left = (stop.tv_sec - now.tv_sec) * 1000000L;
1792 usec_left += stop.tv_usec - now.tv_usec;
1793 timeout2.tv_sec = usec_left / 1000000L;
1794 timeout2.tv_usec = usec_left % 1000000L;
1800 if (readfds != NULL) {
1803 if (writefds != NULL) {
1804 *writefds = tmpwrite;
1806 if (exceptfds != NULL) {
1807 *exceptfds = tmpexcept;
1826#ifndef VRPN_USE_WINSOCK_SOCKETS
1835 ret = write(outfile, buffer + sofar, length - sofar);
1844 }
while ((ret > 0) && (
static_cast<size_t>(sofar) < length));
1846 if (ret == -1)
return (-1);
1847 if (ret == 0)
return (0);
1878 ret = read(infile, buffer + sofar, length - sofar);
1886 }
while ((ret > 0) && (
static_cast<size_t>(sofar) < length));
1888 if (ret == -1)
return (-1);
1889 if (ret == 0)
return (0);
1903 send(outsock, buffer + sofar,
static_cast<int>(length - sofar), 0);
1905 if (nwritten == SOCKET_ERROR) {
1910 }
while (sofar < length);
1912 return static_cast<int>(sofar);
1931 recv(insock, buffer + sofar,
static_cast<int>(length - sofar), 0);
1933 if (nread == SOCKET_ERROR) {
1941 }
while (sofar < length);
1943 return static_cast<int>(sofar);
1961 struct timeval *timeout)
1964 struct timeval timeout2;
1965 struct timeval *timeout2ptr;
1966 struct timeval start, stop, now;
1981 if ((timeout != NULL) &&
1982 ((timeout->tv_sec != 0) || (timeout->tv_usec != 0))) {
1983 timeout2 = *timeout;
1984 timeout2ptr = &timeout2;
1989 timeout2ptr = timeout;
1995 fd_set readfds, exceptfds;
1999 FD_SET(infile, &readfds);
2000 FD_ZERO(&exceptfds);
2001 FD_SET(infile, &exceptfds);
2003 NULL, &exceptfds, timeout2ptr);
2004 if (sel_ret == -1) {
2007 if (FD_ISSET(infile, &exceptfds)) {
2010 if (!FD_ISSET(infile, &readfds)) {
2011 if ((timeout != NULL) && (timeout->tv_sec == 0) &&
2012 (timeout->tv_usec == 0)) {
2013 return static_cast<int>(sofar);
2021 return static_cast<int>(sofar);
2028 if (!FD_ISSET(infile, &readfds)) {
2033#ifndef VRPN_USE_WINSOCK_SOCKETS
2034 ret = read(infile, buffer + sofar, length - sofar);
2044 int nread = recv(infile, buffer + sofar,
2045 static_cast<int>(length - sofar), 0);
2051 }
while ((ret > 0) && (sofar < length));
2052#ifndef VRPN_USE_WINSOCK_SOCKETS
2053 if (ret == -1)
return (-1);
2055 if (ret == 0)
return (0);
2057 return static_cast<int>(sofar);
2070static vrpn_SOCKET open_socket(
int type,
unsigned short *portno,
2071 const char *IPaddress)
2073 struct sockaddr_in name;
2074 struct hostent *phe;
2080 fprintf(stderr,
"open_socket: can't open socket.\n");
2090 vrpn_int32 optval = 1;
2091 vrpn_int32 sockoptsuccess =
2092 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval,
sizeof optval);
2097 namelen =
sizeof(name);
2100 memset((
void *)&name, 0, namelen);
2101 name.sin_family = AF_INET;
2103 name.sin_port = htons(*portno);
2106 name.sin_port = htons(0);
2111 name.sin_addr.s_addr = INADDR_ANY;
2113 else if ((name.sin_addr.s_addr = inet_addr(IPaddress)) == INADDR_NONE) {
2114 if ((phe = gethostbyname(IPaddress)) != NULL) {
2115 memcpy((
void *)&name.sin_addr, (
const void *)phe->h_addr,
2120 fprintf(stderr,
"open_socket: can't get %s host entry\n",
2128 fprintf(stderr,
"open_socket: request port %d, using NIC %d %d %d %d.\n",
2129 portno ? *portno : 0, ntohl(name.sin_addr.s_addr) >> 24,
2130 (ntohl(name.sin_addr.s_addr) >> 16) & 0xff,
2131 (ntohl(name.sin_addr.s_addr) >> 8) & 0xff,
2132 ntohl(name.sin_addr.s_addr) & 0xff);
2135 if (bind(sock, (
struct sockaddr *)&name, namelen) < 0) {
2136 fprintf(stderr,
"open_socket: can't bind address");
2138 fprintf(stderr,
" %d", *portno);
2144 fprintf(stderr,
" (This probably means that another application has "
2145 "the port open already)\n");
2151 if (getsockname(sock, (
struct sockaddr *)&name,
GSN_CAST & namelen)) {
2152 fprintf(stderr,
"vrpn: open_socket: cannot get socket name.\n");
2157 *portno = ntohs(name.sin_port);
2162 fprintf(stderr,
"open_socket: got port %d, using NIC %d %d %d %d.\n",
2163 portno ? *portno : ntohs(name.sin_port),
2164 ntohl(name.sin_addr.s_addr) >> 24,
2165 (ntohl(name.sin_addr.s_addr) >> 16) & 0xff,
2166 (ntohl(name.sin_addr.s_addr) >> 8) & 0xff,
2167 ntohl(name.sin_addr.s_addr) & 0xff);
2177static vrpn_SOCKET open_udp_socket(
unsigned short *portno,
const char *IPaddress)
2179 return open_socket(SOCK_DGRAM, portno, IPaddress);
2186static vrpn_SOCKET open_tcp_socket(
unsigned short *portno = NULL,
2187 const char *NIC_IP = NULL)
2189 return open_socket(SOCK_STREAM, portno, NIC_IP);
2196static vrpn_SOCKET vrpn_connect_udp_port(
const char *machineName,
int remotePort,
2197 const char *NIC_IP = NULL)
2200 struct sockaddr_in udp_name;
2201 struct hostent *remoteHost;
2204 udp_socket = open_udp_socket(NULL, NIC_IP);
2206 udp_namelen =
sizeof(udp_name);
2208 memset((
void *)&udp_name, 0, udp_namelen);
2209 udp_name.sin_family = AF_INET;
2217 if ((udp_name.sin_addr.s_addr = inet_addr(machineName)) == INADDR_NONE) {
2218 remoteHost = gethostbyname(machineName);
2223 u_long foo_mark = 0L;
2224 for (i = 0; i < 4; i++) {
2225 u_long one_char = remoteHost->h_addr_list[0][i];
2226 foo_mark = (foo_mark << 8) | one_char;
2228 udp_name.sin_addr.s_addr = foo_mark;
2230 memcpy(&(udp_name.sin_addr.s_addr), remoteHost->h_addr,
2231 remoteHost->h_length);
2237 "vrpn_connect_udp_port: error finding host by name (%s).\n",
2242#ifndef VRPN_USE_WINSOCK_SOCKETS
2243 udp_name.sin_port = htons(remotePort);
2245 udp_name.sin_port = htons((u_short)remotePort);
2248 if (connect(udp_socket, (
struct sockaddr *)&udp_name, udp_namelen)) {
2249 fprintf(stderr,
"vrpn_connect_udp_port: can't bind udp socket.\n");
2255 udp_namelen =
sizeof(udp_name);
2256 if (getsockname(udp_socket, (
struct sockaddr *)&udp_name,
2258 fprintf(stderr,
"vrpn_connect_udp_port: cannot get socket name.\n");
2266 "vrpn_connect_udp_port: got port %d, using NIC %d %d %d %d.\n",
2267 ntohs(udp_name.sin_port), ntohl(udp_name.sin_addr.s_addr) >> 24,
2268 (ntohl(udp_name.sin_addr.s_addr) >> 16) & 0xff,
2269 (ntohl(udp_name.sin_addr.s_addr) >> 8) & 0xff,
2270 ntohl(udp_name.sin_addr.s_addr) & 0xff);
2299static int get_local_socket_name(
char *local_host,
size_t max_length,
2300 const char *remote_host)
2303 struct sockaddr_in udp_name;
2304 int udp_namelen =
sizeof(udp_name);
2306 vrpn_SOCKET udp_socket = vrpn_connect_udp_port(remote_host, remote_port, NULL);
2309 "get_local_socket_name: cannot connect_udp_port to %s.\n",
2311 fprintf(stderr,
" (returning 0.0.0.0 so we listen on all ports).\n");
2312 udp_name.sin_addr.s_addr = 0;
2315 if (getsockname(udp_socket, (
struct sockaddr *)&udp_name,
2317 fprintf(stderr,
"get_local_socket_name: cannot get socket name.\n");
2324 char myIPstring[100];
2325 int ret = snprintf(myIPstring, 100,
"%d.%d.%d.%d",
2326 ntohl(udp_name.sin_addr.s_addr) >> 24,
2327 (ntohl(udp_name.sin_addr.s_addr) >> 16) & 0xff,
2328 (ntohl(udp_name.sin_addr.s_addr) >> 8) & 0xff,
2329 ntohl(udp_name.sin_addr.s_addr) & 0xff);
2332 if ((
unsigned)strlen(myIPstring) > max_length) {
2333 fprintf(stderr,
"get_local_socket_name: Name too long to return\n");
2363 const int local_port,
2364 const char *NIC_IP = NULL)
2377 if (vrpn_getmyIP(myIPchar,
sizeof(myIPchar), NIC_IP, udp_sock)) {
2379 "vrpn_udp_request_lob_packet: Error finding local hostIP\n");
2383 snprintf(msg, 150,
"%.100s %d", myIPchar, local_port);
2384 msglen =
static_cast<vrpn_int32
>(strlen(msg) +
2388 if (send(udp_sock, msg, msglen, 0) == -1) {
2389 perror(
"vrpn_udp_request_lob_packet: send() failed");
2407static int vrpn_get_a_TCP_socket(
vrpn_SOCKET*listen_sock,
int *listen_portnum,
2408 const char *NIC_IP = NULL)
2410 struct sockaddr_in listen_name;
2413 listen_namelen =
sizeof(listen_name);
2418 *listen_sock = open_tcp_socket(NULL, NIC_IP);
2419 if (*listen_sock < 0) {
2420 fprintf(stderr,
"vrpn_get_a_TCP_socket: socket didn't open.\n");
2424 if (listen(*listen_sock, 1)) {
2425 fprintf(stderr,
"vrpn_get_a_TCP_socket: listen() failed.\n");
2430 if (getsockname(*listen_sock, (
struct sockaddr *)&listen_name,
2432 fprintf(stderr,
"vrpn_get_a_TCP_socket: cannot get socket name.\n");
2437 *listen_portnum = ntohs(listen_name.sin_port);
2458 double timeout = 0.0)
2465 FD_SET(listen_sock, &rfds);
2466 t.tv_sec = (long)(timeout);
2467 t.tv_usec = (long)((timeout - t.tv_sec) * 1000000L);
2470 perror(
"vrpn_poll_for_accept: select() failed");
2473 if (FD_ISSET(listen_sock, &rfds)) {
2476 if ((*accept_sock = accept(listen_sock, 0, 0)) == -1) {
2477 perror(
"vrpn_poll_for_accept: accept() failed");
2480#if !defined(_WIN32_WCE) && !defined(__ANDROID__)
2482 struct protoent *p_entry;
2485 if ((p_entry = getprotobyname(
"TCP")) == NULL) {
2487 "vrpn_poll_for_accept: getprotobyname() failed.\n");
2492 if (setsockopt(*accept_sock, p_entry->p_proto, TCP_NODELAY,
2493 SOCK_CAST & nonzero,
sizeof(nonzero)) == -1) {
2494 perror(
"vrpn_poll_for_accept: setsockopt() failed");
2519static int vrpn_start_server(
const char *machine,
char *server_name,
char *args,
2520 const char *IPaddress = NULL)
2523 #include <TargetConditionals.h>
2524 #if TARGET_IPHONE_SIMULATOR
2527 #elif TARGET_OS_IPHONE
2532#if defined(VRPN_USE_WINSOCK_SOCKETS) || defined(__CYGWIN__) || defined(NO_SYSTEM)
2533 fprintf(stderr,
"VRPN: vrpn_start_server not ported"
2534 " for windows winsock or cygwin!\n");
2535 IPaddress = IPaddress;
2537 server_name = server_name;
2547 if (vrpn_get_a_TCP_socket(&server_sock, &PortNum, IPaddress)) {
2548 fprintf(stderr,
"vrpn_start_server: Cannot get listen socket\n");
2552 if ((pid = fork()) == -1) {
2553 fprintf(stderr,
"vrpn_start_server: cannot fork().\n");
2560 int num_descriptors;
2563 const char *rsh_to_use;
2565 if (vrpn_getmyIP(myIPchar,
sizeof(myIPchar), IPaddress, server_sock)) {
2566 fprintf(stderr,
"vrpn_start_server: Error finding my IP\n");
2573#if defined(__ANDROID__)
2577 num_descriptors = sysconf(_SC_OPEN_MAX);
2579 num_descriptors = getdtablesize();
2582 for (loop = 0; loop < num_descriptors; loop++) {
2583 if ((loop != 1) && (loop != 2)) {
2592 if ((rsh_to_use = (
char *)getenv(
"VRPN_RSH")) == NULL) {
2595 snprintf(command, 600,
"%.100s %.100s %.100s %.100s -client %.100s %d", rsh_to_use, machine,
2596 server_name, args, myIPchar, PortNum);
2597 ret = system(command);
2598 if ((ret == 127) || (ret == -1)) {
2599 fprintf(stderr,
"vrpn_start_server: system() failed !!!!!\n");
2601 fprintf(stderr,
"Attempted command was: '%s'\n", command);
2617 for (waitloop = 0; waitloop < (
SERVCOUNT); waitloop++) {
2623 ret = vrpn_poll_for_accept(server_sock, &child_socket,
SERVWAIT);
2625 fprintf(stderr,
"vrpn_start_server: Accept poll failed\n");
2634 deadkid = waitpid(-1, &status, WNOHANG);
2635 if (deadkid == pid) {
2636 fprintf(stderr,
"vrpn_start_server: server process exited\n");
2643 "vrpn_start_server: server failed to connect in time\n");
2644 fprintf(stderr,
" (took more than %d seconds)\n",
2653 return (child_socket);
2677 snprintf(buffer, length,
"%.16s %c",
vrpn_MAGIC,
2678 static_cast<char>(remote_log_mode +
'0'));
2700 bp = strrchr(buffer,
'.');
2703 fprintf(stderr,
"check_vrpn_cookie: "
2704 "bad cookie (wanted '%s', got '%s'\n",
2711 "check_vrpn_cookie(): "
2712 "VRPN Note: minor version number doesn't match: (prefer '%s', "
2713 "got '%s'). This is not normally a problem.\n",
2737 bp = strrchr(buffer,
'.');
2738 int majorComparison = strncmp(
2740 if (majorComparison > 0 ||
2743 fprintf(stderr,
"check_vrpn_file_cookie: "
2744 "bad cookie (wanted >='%s' and <='%s', "
2751 fprintf(stderr,
"check_vrpn_file_cookie(): "
2752 "Note: Version number doesn't match: (prefer '%s', got "
2753 "'%s'). This is not normally a problem.\n",
2762 vrpn_int32 *connectedEndpointCounter)
2778 vrpn_int32 *connectedEndpointCounter)
2816 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2824 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2835 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2844 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2854 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2862 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2899 fprintf(stderr,
"vrpn_Endpoint_IP::~vrpn_Endpoint_IP: delete failed\n");
2908 fprintf(stderr,
"vrpn_Endpoint_IP::~vrpn_Endpoint_IP: delete failed\n");
2919 fprintf(stderr,
"vrpn_Endpoint_IP::~vrpn_Endpoint_IP: delete failed\n");
2933 return d_types->mapToLocalID(remote_type);
2938 return d_senders->mapToLocalID(remote_sender);
2962 fprintf(stderr,
"vrpn_Endpoint::init: Out of memory!\n");
2984 fd_set readfds, exceptfds;
2985 int tcp_messages_read;
2986 int udp_messages_read;
2988 bool time_to_try_again =
false;
3002 FD_ZERO(&exceptfds);
3020 fprintf(stderr,
"vrpn_Endpoint::mainloop: select failed.\n");
3033 fprintf(stderr,
"vrpn_Endpoint::mainloop: Exception on socket\n");
3042 if (udp_messages_read == -1) {
3043 fprintf(stderr,
"vrpn_Endpoint::mainloop: "
3044 "UDP handling failed, dropping connection\n");
3049 if (udp_messages_read != 0)
3050 printf(
"udp message read = %d\n", udp_messages_read);
3057 if (tcp_messages_read == -1) {
3058 fprintf(stderr,
"vrpn: TCP handling failed, dropping "
3059 "connection (this is normal when a connection "
3066 if (tcp_messages_read) {
3067 printf(
"tcp_message_read %d bytes\n", tcp_messages_read);
3085 printf(
"TRYING_TO_CONNECT\n");
3092 time_to_try_again =
true;
3098 if (time_to_try_again) {
3104 fprintf(stderr,
"vrpn_Endpoint::mainloop: "
3105 "Can't set up new connection!\n");
3117 fprintf(stderr,
"vrpn_Endpoint: mainloop: Bad listen socket\n");
3123 fprintf(stderr,
"vrpn_Endpoint: mainloop: Can't poll for accept\n");
3130 printf(
"vrpn: Connection established\n");
3135 fprintf(stderr,
"vrpn_Endpoint: mainloop: "
3136 "Can't set up new connection!\n");
3148 if (time_to_try_again) {
3165 "vrpn_Endpoint: mainloop: Can't lob UDP request\n");
3181 fprintf(stderr,
"vrpn_Endpoint::mainloop(): "
3182 "Unknown status (%d)\n",
3206 return d_senders->addLocalID(name, which);
3215 return d_types->addLocalID(name, which);
3220 vrpn_int32 local_id)
3222 return d_types->addRemoteEntry(type_name, remote_id, local_id);
3227 vrpn_int32 local_id)
3229 return d_senders->addRemoteEntry(sender_name, remote_id, local_id);
3248 vrpn_int32 type, vrpn_int32 sender,
3250 vrpn_uint32 class_of_service)
3262 if (
d_outLog->logOutgoingMessage(len, time, type, sender, buffer)) {
3263 fprintf(stderr,
"vrpn_Endpoint::pack_message: "
3264 "Couldn't log outgoing message.!\n");
3276 fprintf(stderr,
"vrpn_Endpoint::pack_message: "
3277 "Not connected, so throwing out message.\n");
3312 return (!ret) ? -1 : 0;
3317 vrpn_int32 ret, sent = 0;
3336 "vrpn_Endpoint::send_pending_reports(): No TCP connection\n");
3345 timeout.tv_usec = 0;
3352 NULL, &f, &timeout);
3354 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports(): "
3355 "select() failed.\n");
3372 printf(
"TCP Sent %d bytes\n", ret);
3375 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports: "
3376 "TCP send failed.\n");
3392 printf(
"UDP Sent %d bytes\n", ret);
3395 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports: "
3396 " UDP send failed.");
3416 vrpn_uint32 portparam = portno;
3417 char myIPchar[1000];
3421 fprintf(stderr,
"Getting IP address of NIC %s.\n",
d_NICaddress);
3430 perror(
"vrpn_Endpoint::pack_udp_description: can't get host name");
3440 fprintf(stderr,
"vrpn_Endpoint::pack_udp_description: "
3441 "Packing UDP %s:%d\n",
3446 return pack_message(
static_cast<vrpn_uint32
>(strlen(myIPchar)) + 1, now,
3457 const char *inName =
"";
3458 const char *outName =
"";
3473 2 *
sizeof(vrpn_int32) + strlen(inName) + 1 + strlen(outName) + 1;
3475 try { buf =
new char[bufsize]; }
3476 catch (...) {
return -1; }
3486 vrpn_int32 bufleft =
static_cast<vrpn_int32
>(bufsize);
3487 vrpn_buffer(bp, &bufleft, (vrpn_int32)strlen(inName));
3488 vrpn_buffer(bp, &bufleft, (vrpn_int32)strlen(outName));
3489 vrpn_buffer(bp, &bufleft, inName,
static_cast<vrpn_int32
>(strlen(inName)));
3492 static_cast<vrpn_int32
>(strlen(outName)));
3494 int ret =
pack_message(
static_cast<vrpn_uint32
>(bufsize - bufleft), now,
3500 fprintf(stderr,
"vrpn_Endpoint::pack_log_description: delete failed\n");
3512 timeval localTimeout;
3513 fd_set readfds, exceptfds;
3514 unsigned num_messages_read = 0;
3519 printf(
"vrpn_Endpoint::handle_tcp_messages() called\n");
3523 localTimeout.tv_sec = timeout->tv_sec;
3524 localTimeout.tv_usec = timeout->tv_usec;
3527 localTimeout.tv_sec = 0;
3528 localTimeout.tv_usec = 0;
3541 FD_ZERO(&exceptfds);
3545 NULL, &exceptfds, &localTimeout);
3546 if (sel_ret == -1) {
3547 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: "
3554 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: "
3555 "Exception on socket\n");
3568 num_messages_read++;
3573 if (
d_parent->get_Jane_value() != 0) {
3574 if (num_messages_read >=
d_parent->get_Jane_value()) {
3580 return num_messages_read;
3597 timeval localTimeout;
3598 fd_set readfds, exceptfds;
3599 unsigned num_messages_read = 0;
3604 printf(
"vrpn_Endpoint::handle_udp_messages() called\n");
3608 localTimeout.tv_sec = timeout->tv_sec;
3609 localTimeout.tv_usec = timeout->tv_usec;
3612 localTimeout.tv_sec = 0;
3613 localTimeout.tv_usec = 0;
3625 FD_ZERO(&exceptfds);
3629 &readfds, NULL, &exceptfds, &localTimeout);
3630 if (sel_ret == -1) {
3631 perror(
"vrpn_Endpoint::handle_udp_messages: select failed()");
3637 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_udp_messages: "
3638 "Exception on socket\n");
3650 if (inbuf_len == -1) {
3651 fprintf(stderr,
"vrpn_Endpoint::handle_udp_message: "
3652 "recv() failed.\n");
3661 inbuf_len -= retval;
3662 inbuf_ptr += retval;
3666 num_messages_read++;
3672 if (
d_parent->get_Jane_value() != 0) {
3673 if (num_messages_read >=
d_parent->get_Jane_value()) {
3680 return num_messages_read;
3695 if (sscanf(msg,
"%999s %d", machine, &port) != 2) {
3704 struct sockaddr_in client;
3705 struct hostent *host;
3710 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: "
3711 "can't open socket\n");
3714 client.sin_family = AF_INET;
3722 if ((client.sin_addr.s_addr = inet_addr(addr)) == INADDR_NONE) {
3723 host = gethostbyname(addr);
3729 u_long foo_mark = 0;
3730 for (i = 0; i < 4; i++) {
3731 u_long one_char = host->h_addr_list[0][i];
3732 foo_mark = (foo_mark << 8) | one_char;
3734 client.sin_addr.s_addr = foo_mark;
3737 memcpy(&(client.sin_addr.s_addr), host->h_addr, host->h_length);
3742#if !defined(hpux) && !defined(__hpux) && !defined(_WIN32) && !defined(sparc)
3743 herror(
"gethostbyname error:");
3745 perror(
"gethostbyname error:");
3747 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: "
3748 "error finding host by name (%s)\n",
3754#ifndef VRPN_USE_WINSOCK_SOCKETS
3755 client.sin_port = htons(port);
3757 client.sin_port = htons((u_short)port);
3760 if (connect(
d_tcpSocket, (
struct sockaddr *)&client,
sizeof(client)) < 0) {
3761#ifdef VRPN_USE_WINSOCK_SOCKETS
3763 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: Could not connect "
3764 "to machine %d.%d.%d.%d port %d\n",
3765 (
int)(client.sin_addr.S_un.S_un_b.s_b1),
3766 (
int)(client.sin_addr.S_un.S_un_b.s_b2),
3767 (
int)(client.sin_addr.S_un.S_un_b.s_b3),
3768 (
int)(client.sin_addr.S_un.S_un_b.s_b4),
3769 (
int)(ntohs(client.sin_port)));
3770 int error = WSAGetLastError();
3771 fprintf(stderr,
"Winsock error: %d\n", error);
3774 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: Could not connect to "
3775 "machine %d.%d.%d.%d port %d\n",
3776 (
int)((client.sin_addr.s_addr >> 24) & 0xff),
3777 (
int)((client.sin_addr.s_addr >> 16) & 0xff),
3778 (
int)((client.sin_addr.s_addr >> 8) & 0xff),
3779 (
int)((client.sin_addr.s_addr >> 0) & 0xff),
3780 (
int)(ntohs(client.sin_port)));
3788#if !defined(_WIN32_WCE) && !defined(__ANDROID__)
3790 struct protoent *p_entry;
3793 if ((p_entry = getprotobyname(
"TCP")) == NULL) {
3796 "vrpn_Endpoint::connect_tcp_to: getprotobyname() failed.\n");
3802 if (setsockopt(
d_tcpSocket, p_entry->p_proto, TCP_NODELAY,
3803 SOCK_CAST & nonzero,
sizeof(nonzero)) == -1) {
3804 perror(
"vrpn_Endpoint::connect_tcp_to: setsockopt() failed");
3821 fprintf(stderr,
"vrpn_Endpoint::connect_udp_to: "
3822 "Couldn't open outbound UDP link.\n");
3872 fprintf(stderr,
"vrpn_Endpoint::drop_connection: Can't log\n");
3887 (*d_connectionCounter)--;
3913 fprintf(stderr,
"vrpn_Endpoint_IP::setNICaddress: delete failed\n");
3920 fprintf(stderr,
"Setting endpoint NIC address to %s.\n", address);
3928 fprintf(stderr,
"vrpn_Endpoint::setNICaddress: Out of memory.\n");
3942 memset(sendbuf, 0,
sizeof(sendbuf));
3945 perror(
"vrpn_Endpoint::setup_new_connection: "
3946 "Internal error - array too small. The code's broken.");
3953 fprintf(stderr,
"vrpn_Endpoint::setup_new_connection: "
3954 "Can't write cookie.\n");
3970 timeout = *pTimeout;
3974 timeout.tv_usec = 0;
3977 fd_set readfds, exceptfds;
3986 FD_ZERO(&exceptfds);
3996 &exceptfds, &timeout) == -1) {
3997 fprintf(stderr,
"vrpn_Endpoint::poll_for_cookie(): select failed.\n");
4005 "vrpn_Endpoint::poll_for_cookie(): Exception on socket\n");
4014 "vrpn_Endpoint::poll_for_cookie: cookie handling failed\n"
4015 " while connecting to \"%s\"\n",
4021 printf(
"vrpn_Endpoint::poll_for_cookie() got cookie\n");
4033 memset(recvbuf, 0,
sizeof(recvbuf));
4037 if (ret != sendlen) {
4038 perror(
"vrpn_Endpoint::finish_new_connection_setup: Can't read cookie");
4059 if ((received_logmode < 0) ||
4061 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: "
4062 "Got invalid log mode %d\n",
4063 static_cast<int>(received_logmode));
4079 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: "
4080 "Can't pack remote logging instructions.\n");
4093 unsigned short udp_portnum =
4094 static_cast<unsigned short>(INADDR_ANY);
4097 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: "
4098 "can't open UDP socket\n");
4105 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: "
4106 "Can't pack UDP msg\n");
4115 "CONNECTED - vrpn_Endpoint::finish_new_connection_setup.\n");
4132 "vrpn_Endpoint::finish_new_connection_setup: Can't send UDP msg\n");
4157 (*d_connectionCounter)++;
4165 vrpn_int32 header[5];
4166 struct timeval time;
4167 vrpn_int32 sender, type;
4168 size_t len, payload_len, ceil_len;
4172 fprintf(stderr,
"vrpn_Endpoint::getOneTCPMessage(): something to read\n");
4178 fprintf(stderr,
"vrpn_Endpoint::getOneTCPMessage: "
4179 "Can't read header (this is normal when a connection "
4183 len = ntohl(header[0]);
4184 time.tv_sec = ntohl(header[1]);
4185 time.tv_usec = ntohl(header[2]);
4186 sender = ntohl(header[3]);
4187 type = ntohl(header[4]);
4189 fprintf(stderr,
" header: Len %d, Sender %d, Type %d\n", (
int)len,
4190 (
int)sender, (
int)type);
4194 vrpn_int32 header_len =
sizeof(header);
4198 if (header_len >
static_cast<vrpn_int32
>(
sizeof(header))) {
4202 header_len -
sizeof(header)) !=
4203 (
int)(header_len -
sizeof(header))) {
4204 fprintf(stderr,
"vrpn_Endpoint::getOneTCPMessage: "
4205 "Can't read header + alignment\n");
4213 payload_len = len - header_len;
4214 ceil_len = payload_len;
4221 if (buflen < ceil_len) {
4223 "vrpn: vrpn_Endpoint::getOneTCPMessage: Message too long\n");
4230 perror(
"vrpn: vrpn_Endpoint::getOneTCPMessage: Can't read body");
4234 if (
d_inLog->logIncomingMessage(payload_len, time, type, sender, buf)) {
4235 fprintf(stderr,
"Couldn't log incoming message.!\n");
4239 retval =
dispatch(type, sender, time,
static_cast<vrpn_uint32
>(payload_len),
4250 vrpn_int32 header[5];
4251 struct timeval time;
4252 vrpn_int32 sender, type;
4253 vrpn_uint32 len, payload_len, ceil_len;
4258 vrpn_uint32 header_len =
sizeof(header);
4263 if (header_len > (vrpn_uint32)inbuf_len) {
4264 fprintf(stderr,
"vrpn_Endpoint::getOneUDPMessage: Can't read header");
4267 memcpy(header, inbuf_ptr,
sizeof(header));
4268 inbuf_ptr += header_len;
4269 len = ntohl(header[0]);
4270 time.tv_sec = ntohl(header[1]);
4271 time.tv_usec = ntohl(header[2]);
4272 sender = ntohl(header[3]);
4273 type = ntohl(header[4]);
4276 fprintf(stderr,
"Message type %ld (local type %ld), sender %ld received\n",
4278 fprintf(stderr,
"Message length is %d (buffer length %d).\n", len,
4285 payload_len = len - header_len;
4286 ceil_len = payload_len;
4292 if (header_len + ceil_len > (vrpn_uint32)inbuf_len) {
4293 fprintf(stderr,
"vrpn_Endpoint::getOneUDPMessage: Can't read payload");
4297 if (
d_inLog->logIncomingMessage(payload_len, time, type, sender,
4299 fprintf(stderr,
"Couldn't log incoming message.!\n");
4303 retval =
dispatch(type, sender, time, payload_len, inbuf_ptr);
4308 return ceil_len + header_len;
4312 vrpn_uint32 payload_len,
char *bufptr)
4324 payload_len, bufptr)) {
4331 if (
d_dispatcher->doSystemCallbacksFor(type, sender, time, payload_len,
4333 fprintf(stderr,
"vrpn_Endpoint::dispatch: "
4334 "Nonzero system return\n");
4343 vrpn_int32 &numOut, vrpn_uint32 len,
4344 timeval time, vrpn_int32 type,
4345 vrpn_int32 sender,
const char *buffer,
4346 vrpn_uint32 sequenceNumber)
4351 buffer, sequenceNumber);
4361 sender, buffer, sequenceNumber);
4379 vrpn_uint32 outbuf_size,
4380 vrpn_uint32 initial_out,
4382 struct timeval time,
4388 vrpn_uint32 ceil_len, header_len, total_len;
4389 vrpn_uint32 curr_out = initial_out;
4400 header_len = 5 *
sizeof(vrpn_int32);
4404 total_len = header_len + ceil_len;
4405 if ((curr_out + total_len) > (vrpn_uint32)outbuf_size) {
4419 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(header_len + len);
4420 curr_out +=
sizeof(vrpn_uint32);
4424 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(time.tv_sec);
4425 curr_out +=
sizeof(vrpn_uint32);
4426 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(time.tv_usec);
4427 curr_out +=
sizeof(vrpn_uint32);
4430 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(sender);
4431 curr_out +=
sizeof(vrpn_uint32);
4432 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(type);
4433 curr_out +=
sizeof(vrpn_uint32);
4441 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(seqNo);
4442 curr_out +=
sizeof(vrpn_uint32);
4445 curr_out = initial_out + header_len;
4450 if (buffer != NULL) {
4451 memcpy(&outbuf[curr_out], buffer, len);
4453 curr_out += ceil_len;
4455 printf(
"Marshalled: len %d, ceil_len %d: '", len, ceil_len);
4458 return curr_out - initial_out;
4467 vrpn_int32 local_id;
4470 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_type_message: "
4471 "Type name too long\n");
4476 strncpy(type_name, p.
buffer +
sizeof(vrpn_int32),
4481 i = ntohl(*((
const vrpn_int32 *)p.
buffer));
4482 type_name[i] =
'\0';
4485 printf(
"Registering other-side type: '%s'\n", type_name);
4488 local_id = endpoint->
d_dispatcher->getTypeID(type_name);
4490 if (local_id == -1) {
4496 printf(
"vrpn_Endpoint::handle_type_message: NULL d_parent "
4497 "when trying to auto-register remote message type %s.\n",
4503 fprintf(stderr,
"vrpn: Failed to add remote type %s\n", type_name);
4512 if (inName != NULL) {
4515 if (outName != NULL) {
4539 vrpn_int32 local_id;
4542 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_sender_message():Sender "
4548 strncpy(sender_name, p.
buffer +
sizeof(vrpn_int32),
4553 i = ntohl(*((
const vrpn_int32 *)p.
buffer));
4554 sender_name[i] =
'\0';
4557 printf(
"Registering other-side sender: '%s'\n", sender_name);
4560 local_id = endpoint->
d_dispatcher->getSenderID(sender_name);
4562 if (local_id == -1) {
4568 printf(
"vrpn_Endpoint::handle_sender_message: NULL d_parent "
4569 "when trying to auto-register remote message sender %s\n",
4575 fprintf(stderr,
"vrpn: Failed to add remote sender %s\n", sender_name);
4588 static_cast<vrpn_int32
>(strlen(
d_dispatcher->typeName(which)) + 1);
4590 char buffer[
sizeof(len) +
sizeof(
vrpn_CNAME)];
4592 netlen = htonl(len);
4599 printf(
" vrpn_Connection: Packing type '%s', %d\n",
4602 memcpy(buffer, &netlen,
sizeof(netlen));
4603 memcpy(&buffer[
sizeof(len)],
d_dispatcher->typeName(which),
4607 return pack_message((vrpn_uint32)(len +
sizeof(len)), now,
4618 static_cast<vrpn_int32
>(strlen(
d_dispatcher->senderName(which)) + 1);
4620 char buffer[
sizeof(len) +
sizeof(
vrpn_CNAME)];
4622 netlen = htonl(len);
4629 printf(
" vrpn_Connection: Packing sender '%s'\n",
4632 memcpy(buffer, &netlen,
sizeof(netlen));
4633 memcpy(&buffer[
sizeof(len)],
d_dispatcher->senderName(which),
4637 return pack_message((vrpn_uint32)(len +
sizeof(len)), now,
4644 timeval localTimeout;
4645 fd_set readfds, exceptfds;
4651 localTimeout.tv_sec = 0;
4652 localTimeout.tv_usec = 0;
4660 FD_ZERO(&exceptfds);
4661 FD_SET(fd, &readfds);
4662 FD_SET(fd, &exceptfds);
4664 &exceptfds, &localTimeout);
4665 if (sel_ret == -1) {
4666 fprintf(stderr,
"flush_udp_socket: select failed().");
4671 if (FD_ISSET(fd, &exceptfds)) {
4672 fprintf(stderr,
"flush_udp_socket: Exception on socket.\n");
4677 if (FD_ISSET(fd, &readfds)) {
4680 inbuf_len = recv(fd, buf, 10000, 0);
4681 if (inbuf_len == -1) {
4682 fprintf(stderr,
"flush_udp_socket: recv() failed.\n");
4697 int retval = it->pack_type_description(which);
4710 int retval = it->pack_sender_description(which);
4724 vrpn_int32 inNameLen, outNameLen;
4725 const char **bp = &p.
buffer;
4734 endpoint->
setLogNames(inNameLen == 0 ? NULL : *bp,
4735 outNameLen == 0 ? NULL : *bp + inNameLen + 1);
4736 if (inNameLen > 0) retval = endpoint->
d_inLog->
open();
4737 if (outNameLen > 0) retval = endpoint->
d_outLog->
open();
4752 fprintf(stderr,
"vrpn_Connection::handle_log_message: "
4753 "Remote connection requested logging.\n");
4772 vrpn_int32 type, vrpn_int32 sender,
4774 vrpn_uint32 class_of_service)
4778 printf(
"vrpn_Connection::pack_message: Can't pack because the "
4779 "connection is broken\n");
4785 printf(
"vrpn_Connection::pack_message: bad type (%d)\n", type);
4791 if ((sender < 0) || (sender >=
d_dispatcher->numSenders())) {
4792 printf(
"vrpn_Connection::pack_message: bad sender (%d)\n", sender);
4804 if (it->pack_message(len, time, type, sender, buffer,
4805 class_of_service) != 0) {
4866 it->d_inLog->addFilter(filter, userdata);
4867 it->d_outLog->addFilter(filter, userdata);
4875 int final_retval = 0;
4878 final_retval |= it->d_inLog->saveLogSoFar();
4879 final_retval |= it->d_outLog->saveLogSoFar();
4881 return final_retval;
4949 const char *local_out_logfile_name,
4953 , d_autoDeleteStatus(false)
4963 vrpn_Connection::init(epa);
4969 if (local_out_logfile_name) {
4973 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d "
4974 "Couldn't create endpoint for log file.\n",
4985 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d "
4986 "Couldn't open outgoing log file.\n",
4999 if (local_in_logfile_name) {
5011 const char *local_out_logfile_name,
5012 const char *remote_in_logfile_name,
5013 const char *remote_out_logfile_name,
5018 , d_autoDeleteStatus(false)
5028 vrpn_Connection::init(epa);
5033 fprintf(stderr,
"vrpn_Connection:%d Out of memory.\n", __LINE__);
5042 (((remote_in_logfile_name && strlen(remote_in_logfile_name) > 0)
5045 ((remote_out_logfile_name && strlen(remote_out_logfile_name) > 0)
5048 if (!remote_in_logfile_name) {
5053 new char[strlen(remote_in_logfile_name) + 1];
5061 if (!remote_out_logfile_name) {
5066 new char[strlen(remote_out_logfile_name) + 1];
5077 if (local_in_logfile_name && (strlen(local_in_logfile_name) != 0)) {
5082 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d "
5083 "Couldn't open incoming log file.\n",
5090 if (local_out_logfile_name && (strlen(local_out_logfile_name) != 0)) {
5095 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d "
5096 "Couldn't open local outgoing log file.\n",
5118 fprintf(stderr,
"vrpn_Connection::~vrpn_Connection: delete failed\n");
5124 if (d_references > 0) {
5126 "vrpn_Connection::~vrpn_Connection: "
5127 "Connection was deleted while %d references still remain.\n",
5143 if (d_references == 0 && d_autoDeleteStatus ==
true) {
5147 fprintf(stderr,
"vrpn_Connection::removeReference: delete failed\n");
5150 }
else if (d_references < 0) {
5152 fprintf(stderr,
"vrpn_Connection::removeReference: "
5153 "Negative reference count. This shouldn't happen.");
5161 fprintf(stderr,
"vrpn_Connection::register_sender: "
5162 "%d senders; new name \"%s\"\n",
5170 fprintf(stderr,
"Sender already defined as id %d.\n", retval);
5178 fprintf(stderr,
"Packing sender description for %s, type %d.\n", name,
5191 it->newLocalSender(name, retval);
5202 fprintf(stderr,
"vrpn_Connection::register_message_type: "
5203 "%d type; new name \"%s\"\n",
5211 fprintf(stderr,
"Type already defined as id %d.\n", retval);
5223 fprintf(stderr,
"Packing type description for %s, type %d.\n", name,
5233 it->newLocalType(name, retval);
5245 struct timeval time,
5246 vrpn_uint32 payload_len,
const char *buf)
5248 return d_dispatcher->doCallbacksFor(type, sender, time, payload_len, buf);
5257 char **local_out_logname,
5258 char **remote_in_logname,
5259 char **remote_out_logname)
5268 if (local_in_logname != NULL)
5270 if (local_out_logname != NULL)
5273 if (remote_in_logname != NULL) {
5276 *remote_in_logname =
5281 fprintf(stderr,
"vrpn_Connection::get_log_names(): Out of memory\n");
5283 *remote_in_logname = NULL;
5286 *remote_in_logname = NULL;
5290 if (remote_out_logname != NULL) {
5293 *remote_out_logname =
5299 fprintf(stderr,
"vrpn_Connection::get_log_names(): Out of memory\n");
5301 *remote_out_logname = NULL;
5304 *remote_out_logname = NULL;
5314 vrpn_int32 *connectedEC)
5320 fprintf(stderr,
"vrpn_Connection::get_log_names(): Out of memory\n");
5337 printf(
"Just read disconnect message from logfile\n");
5346 void *userdata, vrpn_int32 sender)
5348 return d_dispatcher->addHandler(type, handler, userdata, sender);
5353 void *userdata, vrpn_int32 sender)
5355 return d_dispatcher->removeHandler(type, handler, userdata, sender);
5372 if (!it->doing_okay()) {
5419 const char *cname,
const char *local_in_logfile_name,
5420 const char *local_out_logfile_name,
const char *remote_in_logfile_name,
5421 const char *remote_out_logfile_name,
const char *NIC_IPaddress,
5422 bool force_connection)
5424 if (cname == NULL) {
5425 fprintf(stderr,
"vrpn_get_connection_by_name(): NULL name\n");
5431 const char *where_at;
5432 if ((where_at = strrchr(cname,
'@')) != NULL) {
5433 cname = where_at + 1;
5437 if (!force_connection) {
5449 int is_file = (0 == strncmp(cname,
"file:", 5));
5454 local_out_logfile_name);
5456 fprintf(stderr,
"vrpn_get_connection_by_name(): Out of memory.");
5463 cname, port, local_in_logfile_name, local_out_logfile_name,
5464 remote_in_logfile_name, remote_out_logfile_name, NIC_IPaddress);
5466 fprintf(stderr,
"vrpn_get_connection_by_name(): Out of memory.");
5474 fprintf(stderr,
"vrpn_get_connection_by_name(): Could not create new connection.");
5509 const char *local_in_logfile_name,
5510 const char *local_out_logfile_name)
5515 if (cname == NULL) {
5516 fprintf(stderr,
"vrpn_create_server_connection(): NULL name\n");
5520 if (location == NULL) {
5523 int is_loopback = (0 == strncmp(cname,
"loopback:", 9));
5524 int is_mpi = (0 == strncmp(cname,
"mpi:", 4));
5527 XXX_implement_MPI_server_connection;
5529 fprintf(stderr,
"vrpn_create_server_connection(): MPI support not "
5530 "compiled in. Set VRPN_USE_MPI in vrpn_Configure.h "
5531 "and recompile.\n");
5535 fprintf(stderr,
"vrpn_create_server_connection: delete failed\n");
5540 }
else if (is_loopback) {
5544 fprintf(stderr,
"vrpn_create_server_connection(): Out of memory\n");
5555 if (strlen(location) == 0) {
5558 local_in_logfile_name,
5559 local_out_logfile_name);
5561 fprintf(stderr,
"vrpn_create_server_connection(): Out of memory\n");
5570 if (strlen(machine) == 0) {
5574 fprintf(stderr,
"vrpn_create_server_connection(): delete failed\n");
5579 unsigned short port =
5583 local_out_logfile_name, machine);
5585 fprintf(stderr,
"vrpn_create_server_connection(): Out of memory\n");
5592 fprintf(stderr,
"vrpn_create_server_connection(): delete failed\n");
5601 fprintf(stderr,
"vrpn_create_server_connection(): delete failed\n");
5606 fprintf(stderr,
"vrpn_create_server_connection(): Could not create new "
5637 fprintf(stderr,
"vrpn_Connection_IP::connect_to_client:"
5638 " Too many existing connections.\n");
5645 fprintf(stderr,
"vrpn_Connection_IP::connect_to_client:"
5646 " Out of memory on new endpoint\n");
5653 snprintf(msg, 256,
"%.200s %d", machine, port);
5654 printf(
"vrpn_Connection_IP::connect_to_client: "
5655 "Connection request received: %s\n",
5673 fprintf(stderr,
"vrpn_Connection_IP::handle_connection(): "
5674 "Can't set up new connection!\n");
5688 char rhostname[1000];
5691 printf(
" Received request for UDP channel to %s\n", p.
buffer);
5712 printf(
" Opened UDP channel to %s:%d\n", rhostname, p.
sender);
5721 if (it->send_pending_reports() != 0) {
5725 fprintf(stderr,
"vrpn_Connection_IP::send_pending_reports: "
5726 "Closing failed endpoint.\n");
5739#ifdef VRPN_USE_WINSOCK_SOCKETS
5746 winStatus = WSAStartup(MAKEWORD(1, 1), &wsaData);
5748 fprintf(stderr,
"vrpn_Connection_IP::init(): "
5749 "Failed to set up sockets.\n");
5750 fprintf(stderr,
"WSAStartup failed with error code %d\n", winStatus);
5763 signal(SIGPIPE, (
void (*)(
int))SIG_IGN);
5765 signal(SIGPIPE, SIG_IGN);
5788 const struct timeval *pTimeout)
5795 timeout = *pTimeout;
5799 timeout.tv_usec = 0;
5810 if (request == -1) {
5812 "vrpn_Connection_IP::server_check_for_incoming_connections(): "
5813 "select failed.\n");
5819 else if (request != 0) {
5820 struct sockaddr_in from;
5821 int fromlen =
sizeof(from);
5825 (
struct sockaddr *)&from,
GSN_CAST & fromlen) == -1) {
5827 "vrpn: Error on recvfrom: Bad connection attempt\n");
5832 msg[
sizeof(msg) - 1] =
'\0';
5838 char fromname[1024];
5839 unsigned long addr_num = ntohl(from.sin_addr.s_addr);
5840 snprintf(fromname, 1024,
"%lu.%lu.%lu.%lu", (addr_num) >> 24,
5841 (addr_num >> 16) & 0xff, (addr_num >> 8) & 0xff,
5843 printf(
"vrpn: Connection request received from %s: %s\n", fromname,
5854 char *checkHost = NULL;
5856 checkHost =
new char[200];
5858 fprintf(stderr,
"vrpn_Connection_IP::server_check_for_incoming_connections(): "
5864 if (sscanf(msg,
"%199s %d", checkHost, &checkPort) != 2) {
5867 "server_check_for_incoming_connections(): Malformed request\n");
5871 fprintf(stderr,
"server_check_for_incoming_connections(): delete failed\n");
5876 checkHost[199] =
'\0';
5877 if (checkPort < 1024) {
5879 "server_check_for_incoming_connections(): Bad port\n");
5883 fprintf(stderr,
"server_check_for_incoming_connections(): delete failed\n");
5891 for (checkLoop = 0; checkLoop < strlen(checkHost); checkLoop++) {
5892 char checkChar = checkHost[checkLoop];
5893 if (!isalnum(checkChar) && (checkChar !=
'.')) {
5896 "server_check_for_incoming_connections(): Bad hostname\n");
5900 fprintf(stderr,
"server_check_for_incoming_connections(): delete failed\n");
5909 fprintf(stderr,
"server_check_for_incoming_connections(): delete failed\n");
5915 fprintf(stderr,
"vrpn: Too many existing connections; "
5916 "ignoring request from %s\n",
5929 "vrpn_Connection_IP::server_check_for_incoming_connections:\n"
5930 " Out of memory on new endpoint\n");
5947 fprintf(stderr,
"vrpn_Connection_IP::server_check_for_incoming_"
5949 "Couldn't open log file.\n");
5981 fprintf(stderr,
"Error accepting on TCP socket.\n");
5986 printf(
"vrpn: TCP connection request received.\n");
5989 fprintf(stderr,
"vrpn: Too many existing connections; "
5990 "ignoring request.\n");
5999 "vrpn_Connection_IP::server_check_for_incoming_connections:\n"
6000 " Out of memory on new endpoint\n");
6013 struct sockaddr_in peer;
6014#ifdef VRPN_USE_WINSOCK_SOCKETS
6015 int peerlen =
sizeof(peer);
6018 int peerlen =
sizeof(peer);
6020 socklen_t peerlen =
sizeof(peer);
6023 unsigned short peer_port = 0;
6024 if (getpeername(newSocket,
static_cast<struct sockaddr *
>(
6025 static_cast<void *
>(&peer)),
6027 peer_port = ntohs(peer.sin_port);
6039 fprintf(stderr,
"vrpn_Connection_IP::server_check_for_incoming_"
6041 "Couldn't open incoming log file.\n");
6113 timeout = *pTimeout;
6117 timeout.tv_usec = 0;
6120 it->mainloop(&timeout);
6122 if (it->status ==
BROKEN) {
6134 unsigned short listen_port_no,
const char *local_in_logfile_name,
6135 const char *local_out_logfile_name,
const char *NIC_IPaddress,
6144 if (NIC_IPaddress != NULL)
try {
6145 char *IP =
new char[strlen(NIC_IPaddress) + 1];
6149 fprintf(stderr,
"vrpn_Connection_IP::vrpn_Connection_IP(): Out of memory.\n");
6171 printf(
"vrpn: Listening for requests on port %d\n", listen_port_no);
6177 fprintf(stderr,
"Couldn't listen on TCP listening socket.\n");
6188 const char *station_name,
int port,
const char *local_in_logfile_name,
6189 const char *local_out_logfile_name,
const char *remote_in_logfile_name,
6190 const char *remote_out_logfile_name,
const char *NIC_IPaddress,
6193 remote_in_logfile_name, remote_out_logfile_name, epa)
6205 if (NIC_IPaddress != NULL)
try {
6206 char *IP =
new char[strlen(NIC_IPaddress) + 1];
6210 fprintf(stderr,
"vrpn_Connection_IP::vrpn_Connection_IP(): Out of memory.\n");
6215 isrsh = (strstr(station_name,
"x-vrsh:") ? VRPN_TRUE : VRPN_FALSE);
6216 istcp = (strstr(station_name,
"tcp:") ? VRPN_TRUE : VRPN_FALSE);
6223 fprintf(stderr,
"vrpn_Connection_IP: First endpoint is null!\n");
6236 if (!isrsh && !istcp) {
6243 "vrpn_Connection_IP: Can't get remote machine name!\n");
6266 fprintf(stderr,
"vrpn_Connection_IP: Can't set up socket to lob "
6275 printf(
"vrpn_Connection_IP: Getting the TCP port to listen on\n");
6280 char local_host[64];
6281 get_local_socket_name(local_host,
sizeof(local_host),
6287 local_host) == -1) {
6289 fprintf(stderr,
"vrpn_Connection_IP: Can't create listen socket\n");
6302 NIC_IPaddress) == -1) {
6304 fprintf(stderr,
"vrpn_Connection_IP: Can't lob UDP request\n");
6330 fprintf(stderr,
"vrpn_Connection_IP: Can't poll for accept\n");
6337 printf(
"vrpn: Connection established on initial try "
6338 "(COOKIE_PENDING)\n");
6343 fprintf(stderr,
"vrpn_Connection_IP: "
6344 "Can't set up new connection!\n");
6358 fprintf(stderr,
"vrpn_Connection_IP: Can't get remote machine name "
6359 "for tcp: connection!\n");
6372 printf(
"vrpn_Connection_IP: Getting the TCP port to connect with.\n");
6382 "vrpn_Connection_IP: Can't create TCP connection.\n");
6390 fprintf(stderr,
"vrpn_Connection_IP: "
6391 "Can't set up new connection!\n");
6405 char *server_program;
6412 token = server_args;
6414 while ((token = strchr(token,
',')) != NULL) {
6418 endpoint->
d_tcpSocket = vrpn_start_server(machinename, server_program,
6419 server_args, NIC_IPaddress);
6422 delete[](
char *)machinename;
6424 fprintf(stderr,
"vrpn_Connection_IP: delete failed\n");
6428 if (server_program) {
6430 delete[](
char *)server_program;
6432 fprintf(stderr,
"vrpn_Connection_IP: delete failed\n");
6438 delete[](
char *)server_args;
6440 fprintf(stderr,
"vrpn_Connection_IP: delete failed\n");
6446 fprintf(stderr,
"vrpn_Connection_IP: "
6460 fprintf(stderr,
"vrpn_Connection_IP: "
6461 "Can't set up new connection!\n");
6491 fprintf(stderr,
"vrpn_Connection_IP::~vrpn_Connection_IP: delete failed\n");
6500#ifdef VRPN_USE_WINSOCK_SOCKETS
6502 if (WSACleanup() == SOCKET_ERROR) {
6503 fprintf(stderr,
"~vrpn_Connection_IP(): "
6504 "WSACleanup() failed with error code %d\n",
6534 if (fullname == NULL) {
6537 size_t len = strcspn(fullname,
"@");
6538 if (len >= MAX_SIZE_T) {
6539 fprintf(stderr,
"vrpn_copy_service_name: String too long!\n");
6545 tbuf =
new char[len];
6546 strncpy(tbuf, fullname, len - 1);
6549 fprintf(stderr,
"vrpn_copy_service_name: Out of memory!\n");
6561 const char *start = fullname;
6562 size_t len = strlen(fullname);
6563 size_t beforeAt = strcspn(fullname,
"@");
6564 if (beforeAt < len) {
6566 start += beforeAt + 1;
6567 len -= beforeAt + 1;
6571 ret =
new char[len];
6574 fprintf(stderr,
"vrpn_copy_service_location: Out of memory!\n");
6582 char *filename = NULL;
6587 if (!fp)
return NULL;
6589 if (!strncmp(fp,
"file://", 7)) {
6591 }
else if (!strncmp(fp,
"file:", 5)) {
6595 len = 1 + strlen(fp);
6598 filename =
new char[len];
6599 strncpy(filename, fp, len);
6600 filename[len - 1] = 0;
6602 fprintf(stderr,
"vrpn_copy_file_name: Out of memory!\n");
6611static int header_len(
const char *hostspecifier)
6615 if (!strncmp(hostspecifier,
"x-vrpn://", 9) ||
6616 !strncmp(hostspecifier,
"x-vrsh://", 9)) {
6619 else if (!strncmp(hostspecifier,
"x-vrpn:", 7) ||
6620 !strncmp(hostspecifier,
"x-vrsh:", 7)) {
6623 else if (!strncmp(hostspecifier,
"tcp://", 6)) {
6626 else if (!strncmp(hostspecifier,
"tcp:", 4)) {
6629 else if (!strncmp(hostspecifier,
"mpi://", 6)) {
6632 else if (!strncmp(hostspecifier,
"mpi:", 4)) {
6645 size_t nearoffset = 0;
6654 nearoffset = header_len(hostspecifier);
6659 faroffset = strcspn(hostspecifier + nearoffset,
":/");
6660 if (faroffset >= MAX_SIZE_T) {
6661 fprintf(stderr,
"vrpn_copy_machine_name: String too long!\n");
6664 len = 1 + faroffset;
6668 tbuf =
new char[len];
6669 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6672 fprintf(stderr,
"vrpn_copy_machine_name: Out of memory!\n");
6687 pn += header_len(hostspecifier);
6689 pn = strrchr(pn,
':');
6700 size_t nearoffset = 0;
6705 nearoffset += header_len(hostspecifier);
6707 nearoffset += strcspn(hostspecifier + nearoffset,
"/");
6709 faroffset = strcspn(hostspecifier + nearoffset,
",");
6710 len = (faroffset ? faroffset : strlen(hostspecifier) - nearoffset);
6711 if (len >= MAX_SIZE_T) {
6712 fprintf(stderr,
"vrpn_copy_rsh_program: String too long!\n");
6717 tbuf =
new char[len];
6718 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6722 fprintf(stderr,
"vrpn_copy_rsh_program: Out of memory!\n");
6730 size_t nearoffset = 0;
6735 nearoffset += header_len(hostspecifier);
6737 nearoffset += strcspn(hostspecifier + nearoffset,
"/");
6738 nearoffset += strcspn(hostspecifier + nearoffset,
",");
6739 faroffset = strlen(hostspecifier);
6740 len = (faroffset - nearoffset) + 1;
6742 tbuf =
new char[len];
6746 fprintf(stderr,
"vrpn_copy_rsh_arguments: Out of memory!\n");
6761 size_t inputLength = strlen(specifier);
6762 size_t atSymbolIndex = strcspn(specifier,
"@");
6764 char *location = NULL;
6766 if (atSymbolIndex == inputLength) {
6769 location =
new char[inputLength + 1];
6772 fprintf(stderr,
"vrpn_set_service_name: Out of memory!\n");
6781 size_t len = strlen(location) + strlen(newServiceName);
6782 char *newSpecifier = NULL;
6784 newSpecifier =
new char[len + 2];
6786 strcat(newSpecifier,
"@");
6787 strcat(newSpecifier, location);
6789 fprintf(stderr,
"vrpn_set_service_name: Out of memory!\n");
6793 fprintf(stderr,
"vrpn_set_service_name: delete failed\n");
6801 fprintf(stderr,
"vrpn_set_service_name: delete failed\n");
6804 return newSpecifier;
Combines the function pointer for an Endpoint Allocator with its two arguments into a single callable...
An iterator that goes forward in an EndpointContainer skipping the NULLs, that also acts a bit like a...
An RAII lock/guard class for vrpn_Semaphore.
void addConnection(vrpn_Connection *, const char *name)
NB implementation is not particularly efficient; we expect to have O(10) connections,...
~vrpn_ConnectionManager(void)
vrpn_Connection * getByName(const char *name)
Searches through d_kcList but NOT d_anonList (Connections constructed with no name)
void deleteConnection(vrpn_Connection *)
static vrpn_ConnectionManager & instance(void)
The only way to get access to an instance of this class. Guarantees that there is only one,...
vrpn_SOCKET listen_udp_sock
UDP Connect requests come here.
virtual void handle_connection(vrpn_Endpoint *endpoint)
This routine is called by a server-side connection when a new connection has just been established,...
virtual int mainloop(const struct timeval *timeout=NULL)
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
virtual ~vrpn_Connection_IP(void)
vrpn_Connection_IP(const char *server_name, int port=vrpn_DEFAULT_LISTEN_PORT_NO, const char *local_in_logfile_name=NULL, const char *local_out_logfile_name=NULL, const char *remote_in_logfile_name=NULL, const char *remote_out_logfile_name=NULL, const char *NIC_IPaddress=NULL, vrpn_EndpointAllocator epa=allocateEndpoint)
Make a client connection. To access this from user code, call vrpn_get_connection_by_name()....
virtual void drop_connection(vrpn_Endpoint *endpoint)
Drops the connection with the given, non-NULL endpoint. Depending on if we're a server or a client,...
virtual int send_pending_reports(void)
send pending report, clear the buffer.
virtual int connect_to_client(const char *machine, int port)
This is similar to check connection except that it can be used to receive requests from before a serv...
void drop_connection_and_compact(vrpn_Endpoint *endpoint)
Like drop_connection, except it includes the call to compact the endpoints. Only safe to call if you ...
virtual void server_check_for_incoming_connections(const struct timeval *timeout=NULL)
static int VRPN_CALLBACK handle_UDP_message(void *userdata, vrpn_HANDLERPARAM p)
Routines that handle system messages.
vrpn_SOCKET listen_tcp_sock
TCP Connection requests come here.
void init(void)
Called by all constructors.
Constructor for a Loopback connection that will basically just pass messages between objects that are...
vrpn_Connection_Loopback()
Make a client connection. To access this from user code, call vrpn_create_server_connection() with a ...
virtual int mainloop(const struct timeval *timeout=NULL)
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
virtual ~vrpn_Connection_Loopback(void)
Generic connection class not specific to the transport mechanism.
vrpn_Connection(const char *local_in_logfile_name, const char *local_out_logfile_name, vrpn_EndpointAllocator epa=allocateEndpoint)
Constructor for server connection. This cannot be called directly any more because vrpn_Connection is...
virtual int do_callbacks_for(vrpn_int32 type, vrpn_int32 sender, struct timeval time, vrpn_uint32 len, const char *buffer)
int delete_endpoint(vrpn_Endpoint *endpoint)
Deletes the endpoint and NULLs the entry in the list of open endpoints.
void addReference()
Counting references to this connection.
virtual int time_since_connection_open(struct timeval *elapsed_time)
Returns the time since the connection opened. Some subclasses may redefine time.
virtual void updateEndpoints(void)
This function will be called on the mainloop() iteration after *d_endpointAllocator is called,...
virtual timeval get_time()
returns the current time in the connection (since the epoch – UTC time).
static int VRPN_CALLBACK handle_log_message(void *userdata, vrpn_HANDLERPARAM p)
Routines that handle system messages.
int message_type_is_registered(const char *) const
Returns message type ID, or -1 if unregistered.
virtual const char * sender_name(vrpn_int32 sender)
Returns the name of the specified sender/type, or NULL if the parameter is invalid....
int doSystemCallbacksFor(vrpn_HANDLERPARAM, void *)
virtual vrpn_int32 register_message_type(const char *name)
virtual vrpn_bool connected(void) const
Returns vrpn_true if the connection has been established, vrpn_false if not (For a networkless connec...
virtual int pack_sender_description(vrpn_int32 which)
Send the sender description to ALL endpoints.
void get_log_names(char **local_in_logname, char **local_out_logname, char **remote_in_logname, char **remote_out_logname)
This function returns the logfile names of this connection in the parameters. It will allocate memory...
int compact_endpoints(void)
Makes sure the endpoint array is set up cleanly for the next pass through.
virtual ~vrpn_Connection(void)
int d_serverLogCount
Server logging w. multiconnection - TCH July 00 Use one "hidden" endpoint for outgoing logs (?...
static vrpn_Endpoint_IP * allocateEndpoint(vrpn_Connection *, vrpn_int32 *connectedEC)
Redefining this and passing it to constructors allows a subclass to use a different subclass of Endpo...
virtual vrpn_File_Connection * get_File_Connection(void)
vrpn_File_Connection implements this as "return this" so it can be used to detect a File_Connection a...
vrpn_int32 d_numConnectedEndpoints
We need to track the number of connected endpoints separately to properly send out got-first-connecti...
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
vrpn_bool d_updateEndpoint
vrpn_TypeDispatcher * d_dispatcher
Derived classes need access to d_dispatcher in their allocateEndpoint() routine. Several compilers wo...
vrpn_int32 d_serverLogMode
virtual int pack_type_description(vrpn_int32 which)
Send the type description to ALL endpoints.
vrpn::EndpointContainer d_endpoints
Sockets used to talk to remote Connection(s) and other information needed on a per-connection basis.
virtual int save_log_so_far()
Save any messages on any endpoints which have been logged so far.
virtual const char * message_type_name(vrpn_int32 type)
virtual vrpn_int32 register_sender(const char *name)
Get a token to use for the string name of the sender or type. Remember to check for -1 meaning failur...
virtual vrpn_bool doing_okay(void) const
Returns vrpn_true if the connection is okay, vrpn_false if not.
virtual int unregister_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
void setAutoDeleteStatus(bool setvalue)
Specify whether this connection should be deleted automatically when it is no longer need (reference ...
int connectionStatus
Status of the connection.
virtual int register_log_filter(vrpn_LOGFILTER filter, void *userdata)
Sets up a filter function for logging. Any user message to be logged is first passed to this function...
timeval start_time
Timekeeping - TCH 30 June 98.
virtual int register_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Set up (or remove) a handler for a message of a given type. Optionally, specify which sender to handl...
static int VRPN_CALLBACK handle_disconnect_message(void *userdata, vrpn_HANDLERPARAM p)
vrpn_uint32 d_stop_processing_messages_after
If this value is greater than zero, the connection should stop looking for new messages on a given en...
vrpn::BoundEndpointAllocator d_boundEndpointAllocator
Function object wrapping an endpoint allocator and binding its arguments.
Encapsulation of the data and methods for a single IP-based connection to take care of one part of ma...
vrpn_int32 tcp_outbuf_size(void) const
vrpn_float64 d_udpAlignedInbuf[vrpn_CONNECTION_UDP_BUFLEN/sizeof(vrpn_float64)+1]
int handle_udp_messages(const timeval *timeout)
virtual ~vrpn_Endpoint_IP(void)
void setNICaddress(const char *)
int connect_tcp_to(const char *msg)
void clearBuffers(void)
Empties out the TCP and UDP send buffers. Needed by vrpn_FileConnection to get at {udp,...
virtual vrpn_bool doing_okay(void) const
vrpn_SOCKET d_udpOutboundSocket
vrpn_int32 d_udpSequenceNumber
virtual int send_pending_reports(void)
send pending report, clear the buffer.
timeval d_last_connect_attempt
When the last UDP lob occurred.
vrpn_bool outbound_udp_open(void) const
True if the UDP outbound is open, False if not.
int handle_tcp_messages(const timeval *timeout)
char * d_remote_machine_name
Machine to call.
vrpn_SOCKET d_udpLobSocket
Socket to use to lob UDP requests asking for the server to call us back.
int getOneTCPMessage(int fd, char *buf, size_t buflen)
vrpn_bool d_tcp_only
For connections made through firewalls or NAT with the tcp: URL, we do not want to allow the endpoint...
int d_tcpListenPort
Socket and port that the client listens on when lobbing datagrams at the server and waiting for it to...
vrpn_Endpoint_IP(vrpn_TypeDispatcher *dispatcher, vrpn_int32 *connectedEndpointCounter)
int d_remote_port_number
Port to connect to on remote machine.
int pack_udp_description(int portno)
vrpn_SOCKET d_tcpListenSocket
This section deals with when a client connection is trying to establish (or re-establish) a connectio...
int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called.
vrpn_SOCKET d_udpInboundSocket
Inbound unreliable messages come here. Need one for each due to different clock synchronization for e...
int getOneUDPMessage(char *buf, size_t buflen)
int mainloop(timeval *timeout)
int connect_udp_to(const char *addr, int port)
Connects d_udpSocket to the specified address and port; returns 0 on success, sets status to BROKEN a...
vrpn_int32 udp_outbuf_size(void) const
vrpn_float64 d_tcpAlignedInbuf[vrpn_CONNECTION_TCP_BUFLEN/sizeof(vrpn_float64)+1]
int setup_new_connection(void)
Sends the magic cookie and other information to its peer. It is called by both the client and server ...
void poll_for_cookie(const timeval *timeout=NULL)
vrpn_int32 d_tcpSequenceNumber
int finish_new_connection_setup(void)
void drop_connection(void)
Should only be called by vrpn_Connection::drop_connection(), since there's more housecleaning to do a...
Encapsulation of the data and methods for a single generic connection to take care of one part of man...
void setConnection(vrpn_Connection *conn)
int local_type_id(vrpn_int32 remote_type) const
Returns the local mapping for the remote type (-1 if none).
static int VRPN_CALLBACK handle_type_message(void *userdata, vrpn_HANDLERPARAM p)
int tryToMarshall(char *outbuf, vrpn_int32 &buflen, vrpn_int32 &numOut, vrpn_uint32 len, timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 classOfService)
Calls marshall_message(); if that fails, calls send_pending_reports() and then marshalls again....
long d_remoteLogMode
Mode to put the remote logging in.
int newRemoteType(vrpn_CNAME type_name, vrpn_int32 remote_id, vrpn_int32 local_id)
Adds a new remote type/sender and returns its index. Returns -1 on error.
void clear_other_senders_and_types(void)
Clear out the remote mapping list. This is done when a connection is dropped and we want to try and r...
vrpn_TypeDispatcher * d_dispatcher
virtual ~vrpn_Endpoint(void)
virtual int send_pending_reports(void)=0
send pending report, clear the buffer. This function was protected, now is public,...
virtual int setup_new_connection(void)=0
Sends the magic cookie and other information to its peer. It is called by both the client and server ...
int pack_sender_description(vrpn_int32 which)
Packs a sender description over our socket.
int marshall_message(char *outbuf, vrpn_uint32 outbuf_size, vrpn_uint32 initial_out, vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 sequenceNumber)
Marshal the message into the buffer if it will fit.
virtual void drop_connection(void)=0
Should only be called by vrpn_Connection::drop_connection(), since there's more housecleaning to do a...
static int VRPN_CALLBACK handle_sender_message(void *userdata, vrpn_HANDLERPARAM p)
vrpn_int32 * d_connectionCounter
int newRemoteSender(vrpn_CNAME sender_name, vrpn_int32 remote_id, vrpn_int32 local_id)
char * d_remoteInLogName
Name of the remote log file.
int pack_log_description(void)
Packs the log description set by setup_new_connection().
virtual int dispatch(vrpn_int32 type, vrpn_int32 sender, timeval time, vrpn_uint32 payload_len, char *bufptr)
int newLocalType(const char *name, vrpn_int32 which)
vrpn_Endpoint(vrpn_TypeDispatcher *dispatcher, vrpn_int32 *connectedEndpointCounter)
int local_sender_id(vrpn_int32 remote_sender) const
Returns the local mapping for the remote sender (-1 if none).
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)=0
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
vrpn_TranslationTable * d_senders
vrpn_Connection * d_parent
int newLocalSender(const char *name, vrpn_int32 which)
A new local sender or type has been established; set the local type for it if the other side has decl...
int pack_type_description(vrpn_int32 which)
Packs a type description.
void setLogNames(const char *inName, const char *outName)
vrpn_TranslationTable * d_types
char * d_remoteOutLogName
Name of the remote log file.
vrpn_bool d_wroteMagicCookie
int setCookie(const char *cookieBuffer)
The magic cookie is set to the default value of the version of VRPN compiled, but a more correct valu...
int addFilter(vrpn_LOGFILTER filter, void *userdata)
char * getName()
Allocates a new string and copies the log file name to it. IMPORTANT: code calling this function is r...
vrpn_Log(vrpn_TranslationTable *senders, vrpn_TranslationTable *types)
vrpn_TranslationTable * d_senders
int setName(const char *name)
int checkFilters(vrpn_int32 payloadLen, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer)
int setCompoundName(const char *name, int index)
Takes a name of the form foo.bar and an index <n> and sets the name of the log file to be foo-<n>....
int open(void)
Opens the log file.
vrpn_TranslationTable * d_types
long & logMode(void)
Returns a reference so we can |= it.
vrpnLogFilterEntry * d_filters
int saveLogSoFar(void)
Saves any messages logged so far.
vrpn_LOGLIST * d_firstEntry
int logIncomingMessage(size_t payloadLen, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer)
Should be called with the timeval adjusted by the clock offset on the receiving Endpoint.
timeval lastLogTime()
Returns the time of the last message that was logged.
int logMessage(vrpn_int32 payloadLen, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_bool isRemote=VRPN_FALSE)
We'd like to make this protected, but there's one place it needs to be exposed, at least until we get...
int logOutgoingMessage(vrpn_int32 payloadLen, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer)
int close(void)
Closes and saves the log file.
void assign(size_type count, const T &value)
vrpn_LOGFILTER filter
routine to call
void * userdata
passed along
vrpnLogFilterEntry * next
Description of a callback entry for a user type.
vrpnMsgCallbackEntry * next
Next handler.
void * userdata
Passed along.
vrpn_int32 sender
Only if from sender.
vrpn_MESSAGEHANDLER handler
Routine to call.
This structure is what is passed to a vrpn_Connection message callback.
Placed here so vrpn_FileConnection can use it too.
size_t vrpn_cookie_size(void)
Returns the size of the magic cookie buffer, plus any alignment overhead.
int write_vrpn_cookie(char *buffer, size_t length, long remote_log_mode)
Writes the magic cookie into buffer with given length.
char * vrpn_copy_file_name(const char *filespecifier)
Utility routines to parse file specifiers FROM service locations.
const char * vrpn_CONTROL
vrpn_CONTROL is the sender used for notification messages sent to the user from the local VRPN implem...
const char * vrpn_got_first_connection
These are the strings that define the system-generated message types that tell when connections are r...
char * vrpn_copy_machine_name(const char *hostspecifier)
#define vrpn_CONNECTION_MAX_XLATION_TABLE_SIZE
const char * vrpn_FILE_MAGIC
vrpn_Connection * vrpn_create_server_connection(const char *cname, const char *local_in_logfile_name, const char *local_out_logfile_name)
Create a server connection of arbitrary type (VRPN UDP/TCP, TCP, File, Loopback, MPI).
char * vrpn_copy_service_name(const char *fullname)
int vrpn_udp_request_lob_packet(vrpn_SOCKET udp_sock, const char *, const int, const int local_port, const char *NIC_IP=NULL)
This section deals with implementing a method of connection termed a UDP request.
const char * vrpn_dropped_last_connection
#define vrpn_socket_error_to_chars(x)
const size_t vrpn_COOKIE_SIZE
#define vrpn_socket_error
int vrpn_noint_select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
This routine will perform like a normal select() call, but it will restart if it quit because of an i...
char * vrpn_copy_rsh_program(const char *hostspecifier)
char * vrpn_copy_rsh_arguments(const char *hostspecifier)
char * vrpn_copy_service_location(const char *fullname)
const char * vrpn_dropped_connection
int vrpn_noint_block_read_timeout(vrpn_SOCKET infile, char buffer[], size_t length, struct timeval *timeout)
This routine will read in a block from the file descriptor.
vrpn_Connection * vrpn_get_connection_by_name(const char *cname, const char *local_in_logfile_name, const char *local_out_logfile_name, const char *remote_in_logfile_name, const char *remote_out_logfile_name, const char *NIC_IPaddress, bool force_connection)
Create a client connection of arbitrary type (VRPN UDP/TCP, TCP, File, Loopback, MPI).
char * vrpn_set_service_name(const char *specifier, const char *newServiceName)
Utility routine to rename the service name of a given host specifier.
int vrpn_noint_block_read(int infile, char buffer[], size_t length)
int vrpn_noint_block_write(int outfile, const char buffer[], size_t length)
const char * vrpn_got_connection
int check_vrpn_cookie(const char *buffer)
Checks to see if the given buffer has the magic cookie.
int check_vrpn_file_cookie(const char *buffer)
int vrpn_get_port_number(const char *hostspecifier)
const vrpn_int32 vrpn_CONNECTION_UDP_DESCRIPTION
const int vrpn_CONNECTION_UDP_BUFLEN
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
VRPN_API char * vrpn_copy_rsh_arguments(const char *hostspecifier)
const vrpn_int32 vrpn_CONNECTION_LOG_DESCRIPTION
const int vrpn_CONNECTION_MAX_SENDERS
Types now have their storage dynamically allocated, so we can afford to have large tables....
const vrpn_int32 vrpn_CONNECTION_TYPE_DESCRIPTION
const int vrpn_ANY_SENDER
vrpn_ANY_SENDER can be used to register callbacks on a given message type from any sender.
VRPN_API int check_vrpn_cookie(const char *buffer)
Checks the buffer to see if it is a valid VRPN header cookie. Returns -1 on total mismatch,...
const unsigned vrpn_ALIGN
VRPN buffers are aligned on 8 byte boundaries so that we can pack and unpack doubles into them on arc...
int VRPN_API vrpn_noint_select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
This routine will perform like a normal select() call, but it will restart if it quit because of an i...
VRPN_API int write_vrpn_cookie(char *buffer, size_t length, long remote_log_mode)
Writes the magic cookie into buffer with given length.
vrpn_Endpoint_IP *(* vrpn_EndpointAllocator)(vrpn_Connection *connection, vrpn_int32 *numActiveConnections)
Function pointer to an endpoint allocator.
class VRPN_API vrpn_Endpoint_IP
vrpn_MESSAGEHANDLER vrpn_LOGFILTER
Type of handler for filters on logfiles is the same as connection handler.
const int vrpn_ANY_TYPE
vrpn_ANY_TYPE can be used to register callbacks for any USER type of message from a given sender....
int(VRPN_CALLBACK * vrpn_MESSAGEHANDLER)(void *userdata, vrpn_HANDLERPARAM p)
Type of a message handler for vrpn_Connection messages.
VRPN_API const char * vrpn_CONTROL
vrpn_CONTROL is the sender used for notification messages sent to the user from the local VRPN implem...
VRPN_API char * vrpn_copy_service_location(const char *fullname)
class VRPN_API vrpn_File_Connection
class VRPN_API vrpn_TypeDispatcher
VRPN_API const char * vrpn_dropped_connection
VRPN_API const char * vrpn_got_first_connection
These are the strings that define the system-generated message types that tell when connections are r...
VRPN_API const char * vrpn_got_connection
class VRPN_API vrpn_TranslationTable
const int vrpn_CONNECTION_MAX_TYPES
VRPN_API char * vrpn_copy_rsh_program(const char *hostspecifier)
const vrpn_int32 vrpn_CONNECTION_DISCONNECT_MESSAGE
const int vrpn_CONNECTION_TCP_BUFLEN
VRPN_API char * vrpn_copy_machine_name(const char *hostspecifier)
int VRPN_API vrpn_noint_block_write(int outfile, const char buffer[], size_t length)
const vrpn_int32 vrpn_CONNECTION_SENDER_DESCRIPTION
VRPN_API const char * vrpn_dropped_last_connection
char vrpn_CNAME[vrpn_CNAME_LENGTH]
const long vrpn_LOG_OUTGOING
const long vrpn_LOG_INCOMING
VRPN_API size_t vrpn_cookie_size(void)
Returns the size of the magic cookie buffer, plus any alignment overhead.
int VRPN_API vrpn_noint_block_read(int infile, char buffer[], size_t length)
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
bool vrpn_TimevalGreater(const timeval &tv1, const timeval &tv2)
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message.
timeval vrpn_TimevalDiff(const timeval &tv1, const timeval &tv2)
timeval vrpn_TimevalSum(const timeval &tv1, const timeval &tv2)
void vrpn_strcpy(char(&to)[charCount], const char *pSrc)
Null-terminated-string copy function that both guarantees not to overrun the buffer and guarantees th...
#define vrpn_gettimeofday
char * vrpn_strncpynull(char *dst, const char *src, size_t size)
Version of strncpy that ensures the resulting string is alyways NULL terminated. It also only writes ...