31 #ifdef VRPN_USE_WINSOCK_SOCKETS 33 #define vrpn_closeSocket closesocket 35 #define vrpn_closeSocket close 36 #include <arpa/inet.h> 37 #include <netinet/in.h> 38 #include <sys/socket.h> 47 #include <arpa/inet.h> 49 #define INADDR_NONE -1 57 #include <arpa/nameser.h> 61 #ifndef VRPN_USE_WINSOCK_SOCKETS 64 #include <netinet/tcp.h> 69 #ifdef VRPN_USE_WINSOCK_SOCKETS 70 #define SOCK_CAST (char *) 72 #define errno WSAGetLastError() 73 #define EINTR WSAEINTR 77 #define SOCK_CAST (const char *) 83 #if defined(_AIX) || defined(__APPLE__) || defined(ANDROID) || defined(__linux) 84 #define GSN_CAST (socklen_t *) 87 #define GSN_CAST (unsigned int *) 97 int gethostname(
char *,
int);
111 #ifndef VRPN_USE_WINSOCK_SOCKETS 112 #define INVALID_SOCKET -1 117 #pragma warning(disable : 4127) 188 "VRPN_Connection_Dropped_Last_Connection";
203 extern int getdtablesize(
void);
204 pid_t wait3(
int *statusp,
int options,
struct rusage *rusage);
212 #define getdtablesize() MAXFUPLIM 216 #define getdtablesize() MAXFUPLIM 225 #define RSH (char *) "/usr/local/bin/ssh" 227 #define RSH (char *) "/usr/local/bin/rsh" 232 #define UDP_CALL_TIMEOUT (2) 233 #define UDP_CALL_RETRIES (5) 239 #define SERVCOUNT (20) 240 #define SERVWAIT (120 / SERVCOUNT) 245 #define vrpn_CONNECTION_MAX_XLATION_TABLE_SIZE 2000 293 struct cRemoteMapping {
295 vrpn_int32 remote_id;
307 vrpn_int32 numEntries(
void)
const;
308 vrpn_int32 mapToLocalID(vrpn_int32 remote_id)
const;
315 vrpn_int32 addRemoteEntry(
cName name, vrpn_int32 remote_id,
316 vrpn_int32 local_id);
321 vrpn_bool addLocalID(
const char *name, vrpn_int32 local_id);
326 vrpn_int32 d_numEntries;
336 d_entry[i].name = NULL;
337 d_entry[i].remote_id = -1;
338 d_entry[i].local_id = -1;
342 vrpn_TranslationTable::~vrpn_TranslationTable(
void) { clear(); }
344 vrpn_int32 vrpn_TranslationTable::numEntries(
void)
const 349 vrpn_int32 vrpn_TranslationTable::mapToLocalID(vrpn_int32 remote_id)
const 351 if ((remote_id < 0) || (remote_id > d_numEntries)) {
355 fprintf(stderr,
"vrpn_TranslationTable::mapToLocalID: " 356 "Remote ID %d is illegal!\n",
364 fprintf(stderr,
"Remote ID %d maps to local ID %d (%s).\n", remote_id,
365 d_entry[remote_id].local_id, d_entry[remote_id].name);
368 return d_entry[remote_id].local_id;
371 vrpn_int32 vrpn_TranslationTable::addRemoteEntry(
cName name,
372 vrpn_int32 remote_id,
377 useEntry = remote_id;
380 fprintf(stderr,
"vrpn_TranslationTable::addRemoteEntry: " 381 "Too many entries in table (%d).\n",
392 if (!d_entry[useEntry].name) {
393 d_entry[useEntry].name =
new cName;
394 if (!d_entry[useEntry].name) {
395 fprintf(stderr,
"vrpn_TranslationTable::addRemoteEntry: " 401 memcpy(d_entry[useEntry].name, name,
sizeof(
cName));
402 d_entry[useEntry].remote_id = remote_id;
403 d_entry[useEntry].local_id = local_id;
406 fprintf(stderr,
"Set up remote ID %d named %s with local equivalent %d.\n",
407 remote_id, name, local_id);
410 if (d_numEntries <= useEntry) {
411 d_numEntries = useEntry + 1;
417 vrpn_bool vrpn_TranslationTable::addLocalID(
const char *name,
422 for (i = 0; i < d_numEntries; i++) {
423 if (d_entry[i].name && !strcmp(d_entry[i].name, name)) {
424 d_entry[i].local_id = local_id;
431 void vrpn_TranslationTable::clear(
void)
435 for (i = 0; i < d_numEntries; i++) {
436 if (d_entry[i].name) {
437 delete[] d_entry[i].name;
438 d_entry[i].name = NULL;
440 d_entry[i].local_id = -1;
441 d_entry[i].remote_id = -1;
447 : d_logFileName(NULL)
452 , d_magicCookie(NULL)
453 , d_wroteMagicCookie(vrpn_FALSE)
467 fprintf(stderr,
"vrpn_Log: Out of memory.\n");
508 fprintf(stderr,
"vrpn_Log::open: Log file has no name.\n");
512 fprintf(stderr,
"vrpn_Log::open: Log file is already open.\n");
520 fprintf(stderr,
"vrpn_Log::open: " 521 "Log file \"%s\" already exists.\n",
529 fprintf(stderr,
"vrpn_Log::open: " 530 "Couldn't open log file \"%s\": ",
538 d_file = fopen(
"/tmp/vrpn_emergency_log",
"r");
542 perror(
"vrpn_Log::open_log: " 543 "Emergency log file \"/tmp/vrpn_emergency_log\" " 544 "already exists.\n");
547 d_file = fopen(
"/tmp/vrpn_emergency_log",
"wb");
549 perror(
"vrpn_Log::open: " 550 "Couldn't open emergency log file " 551 "\"/tmp/vrpn_emergency_log\": ");
559 fprintf(stderr,
"Writing to /tmp/vrpn_emergency_log instead.\n");
568 int final_retval = 0;
572 fprintf(stderr,
"vrpn_Log::close: " 573 "close of log file failed!\n");
590 int final_retval = 0;
598 fprintf(stderr,
"vrpn_Log::saveLogSoFar: " 599 "Log file is not open!\n");
620 fprintf(stderr,
"vrpn_Log::saveLogSoFar: " 621 "Couldn't write magic cookie to log file " 622 "(got %d, expected %d).\n",
623 static_cast<int>(retval),
643 vrpn_int32 values[6];
645 memcpy(&(values[0]), &lp->
data.
type,
sizeof(vrpn_int32));
646 memcpy(&(values[1]), &lp->
data.
sender,
sizeof(vrpn_int32));
647 memcpy(&(values[2]), &lp->
data.
msg_time.tv_sec,
sizeof(vrpn_int32));
648 memcpy(&(values[3]), &lp->
data.
msg_time.tv_usec,
sizeof(vrpn_int32));
650 memcpy(&(values[5]), &zero,
sizeof(vrpn_int32));
651 retval = fwrite(values,
sizeof(vrpn_int32), 6,
d_file);
655 "vrpn_Log::saveLogSoFar: " 656 "Couldn't write log file (got %d, expected %lud).\n",
657 static_cast<int>(retval),
658 static_cast<unsigned long>(
sizeof(lp->
data)));
671 if (retval != host_len) {
672 fprintf(stderr,
"vrpn_Log::saveLogSoFar: " 673 "Couldn't write log file.\n");
684 delete[](
char *)
d_logTail -> data.buffer;
696 vrpn_int32 type, vrpn_int32 sender,
706 return logMessage(static_cast<vrpn_int32>(payloadLen), time, type,
707 sender, buffer, vrpn_TRUE);
715 vrpn_int32 type, vrpn_int32 sender,
720 return logMessage(payloadLen, time, type, sender, buffer);
727 vrpn_int32 type, vrpn_int32 sender,
const char *buffer,
731 vrpn_int32 effectiveType;
732 vrpn_int32 effectiveSender;
735 effectiveType =
d_types->mapToLocalID(type);
736 effectiveSender =
d_senders->mapToLocalID(sender);
739 effectiveType = type;
740 effectiveSender = sender;
745 if (
checkFilters(payloadLen, time, effectiveType, effectiveSender,
755 fprintf(stderr,
"vrpn_Log::logMessage: " 771 if (payloadLen > 0) {
774 fprintf(stderr,
"vrpn_Log::logMessage: " 781 memcpy((
char *)lp->
data.
buffer, buffer, payloadLen);
807 dot = strrchr(name,
'.');
810 strncpy(newName, name, dot - name);
811 newName[dot - name] = 0;
814 strcpy(newName, name);
816 len = strlen(newName);
817 sprintf(newName + len,
"-%d", index);
819 strcat(newName, dot);
835 fprintf(stderr,
"vrpn_Log::setName: Out of memory!\n");
852 fprintf(stderr,
"vrpn_Log::setCookie: Out of memory.\n");
868 fprintf(stderr,
"vrpn_Log::addFilter: Out of memory.\n");
872 newEntry->
filter = filter;
883 vrpn_int32 type, vrpn_int32 sender,
921 int numTypes(
void)
const;
922 const char *typeName(
int which)
const;
924 vrpn_int32 getTypeID(
const char *name);
927 int numSenders(
void)
const;
928 const char *senderName(
int which)
const;
930 vrpn_int32 getSenderID(
const char *name);
935 vrpn_int32 addType(
const char *name);
936 vrpn_int32 addSender(
const char *name);
938 vrpn_int32 registerType(
const char *name);
943 vrpn_int32 registerSender(
const char *name);
951 void *userdata, vrpn_int32 sender);
958 int doCallbacksFor(vrpn_int32 type, vrpn_int32 sender, timeval time,
959 vrpn_uint32 len,
const char *buffer);
960 int doSystemCallbacksFor(vrpn_int32 type, vrpn_int32 sender, timeval time,
961 vrpn_uint32 len,
const char *buffer,
968 struct vrpnLocalMapping {
988 , d_genericCallbacks(NULL)
1000 vrpn_TypeDispatcher::~vrpn_TypeDispatcher(
void)
1005 for (i = 0; i < d_numTypes; i++) {
1006 if (d_types[i].name) {
1007 delete[] d_types[i].name;
1009 pVMCB = d_types[i].who_cares;
1012 pVMCB = pVMCB_Del->
next;
1017 pVMCB = d_genericCallbacks;
1021 pVMCB = pVMCB_Del->
next;
1029 int vrpn_TypeDispatcher::numTypes(
void)
const {
return d_numTypes; }
1031 const char *vrpn_TypeDispatcher::typeName(
int i)
const 1033 if ((i < 0) || (i >= d_numTypes)) {
1036 return d_types[i].name;
1039 vrpn_int32 vrpn_TypeDispatcher::getTypeID(
const char *name)
1043 for (i = 0; i < d_numTypes; i++) {
1044 if (!strcmp(name, d_types[i].name)) {
1052 int vrpn_TypeDispatcher::numSenders(
void)
const {
return d_numSenders; }
1054 const char *vrpn_TypeDispatcher::senderName(
int i)
const 1056 if ((i < 0) || (i >= d_numSenders)) {
1059 return d_senders[i];
1062 vrpn_int32 vrpn_TypeDispatcher::getSenderID(
const char *name)
1066 for (i = 0; i < d_numSenders; i++) {
1067 if (!strcmp(name, d_senders[i])) {
1075 vrpn_int32 vrpn_TypeDispatcher::addType(
const char *name)
1080 fprintf(stderr,
"vrpn_TypeDispatcher::addType: " 1086 if (!d_types[d_numTypes].name) {
1087 d_types[d_numTypes].name =
new cName;
1088 if (!d_types[d_numTypes].name) {
1089 fprintf(stderr,
"vrpn_TypeDispatcher::addType: " 1090 "Can't allocate memory for new record.\n");
1096 strncpy(d_types[d_numTypes].name, name,
sizeof(
cName) - 1);
1097 d_types[d_numTypes].who_cares = NULL;
1098 d_types[d_numTypes].cCares = 0;
1101 return d_numTypes - 1;
1104 vrpn_int32 vrpn_TypeDispatcher::addSender(
const char *name)
1109 fprintf(stderr,
"vrpn_TypeDispatcher::addSender: " 1110 "Too many! (%d).\n",
1115 if (!d_senders[d_numSenders]) {
1119 d_senders[d_numSenders] =
new cName;
1120 if (!d_senders[d_numSenders]) {
1121 fprintf(stderr,
"vrpn_TypeDispatcher::addSender: " 1122 "Can't allocate memory for new record\n");
1128 strncpy(d_senders[d_numSenders], name,
sizeof(
cName) - 1);
1132 return d_numSenders - 1;
1135 vrpn_int32 vrpn_TypeDispatcher::registerType(
const char *name)
1140 retval = getTypeID(name);
1145 return addType(name);
1148 vrpn_int32 vrpn_TypeDispatcher::registerSender(
const char *name)
1153 retval = getSenderID(name);
1158 return addSender(name);
1161 int vrpn_TypeDispatcher::addHandler(vrpn_int32 type,
1170 if (((type < 0) || (type >= d_numTypes)) && (type !=
vrpn_ANY_TYPE)) {
1171 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: No such type\n");
1177 ((sender < 0) || (sender >= d_numSenders))) {
1178 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: No such sender\n");
1183 if (handler == NULL) {
1184 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: NULL handler\n");
1190 if (new_entry == NULL) {
1191 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: Out of memory\n");
1196 new_entry->
sender = sender;
1199 printf(
"Adding user handler for type %ld, sender %ld\n", type, sender);
1208 ptr = &d_genericCallbacks;
1211 ptr = &d_types[type].who_cares;
1215 ptr = &((*ptr)->next);
1218 new_entry->
next = NULL;
1223 int vrpn_TypeDispatcher::removeHandler(vrpn_int32 type,
1225 void *userdata, vrpn_int32 sender)
1232 if (((type < 0) || (type >= d_numTypes)) && (type !=
vrpn_ANY_TYPE)) {
1233 fprintf(stderr,
"vrpn_TypeDispatcher::removeHandler: No such type\n");
1240 snitch = &d_genericCallbacks;
1243 snitch = &(d_types[type].who_cares);
1246 while ((victim != NULL) &&
1248 (victim->
sender != sender))) {
1249 snitch = &((*snitch)->next);
1250 victim = victim->
next;
1254 if (victim == NULL) {
1256 "vrpn_TypeDispatcher::removeHandler: No such handler\n");
1261 *snitch = victim->
next;
1267 void vrpn_TypeDispatcher::setSystemHandler(vrpn_int32 type,
1270 d_systemMessages[-type] = handler;
1273 int vrpn_TypeDispatcher::doCallbacksFor(vrpn_int32 type, vrpn_int32 sender,
1274 timeval time, vrpn_uint32 len,
1285 if (type >= d_numTypes) {
1297 who = d_genericCallbacks;
1303 fprintf(stderr,
"vrpn_TypeDispatcher::doCallbacksFor: " 1304 "Nonzero user generic handler return.\n");
1314 who = d_types[type].who_cares;
1319 fprintf(stderr,
"vrpn_TypeDispatcher::doCallbacksFor: " 1320 "Nonzero user handler return.\n");
1332 int vrpn_TypeDispatcher::doSystemCallbacksFor(vrpn_int32 type,
1333 vrpn_int32 sender, timeval time,
1344 fprintf(stderr,
"vrpn_TypeDispatcher::doSystemCallbacksFor: " 1345 "Illegal type %d.\n",
1350 if (!d_systemMessages[-type]) {
1361 return doSystemCallbacksFor(p, userdata);
1373 fprintf(stderr,
"vrpn_TypeDispatcher::doSystemCallbacksFor: " 1374 "Illegal type %d.\n",
1379 if (!d_systemMessages[-p.
type]) {
1383 retval = d_systemMessages[-p.
type](userdata, p);
1385 fprintf(stderr,
"vrpn_TypeDispatcher::doSystemCallbacksFor: " 1386 "Nonzero system handler return.\n");
1392 void vrpn_TypeDispatcher::clear(
void)
1397 d_types[i].who_cares = NULL;
1398 d_types[i].cCares = 0;
1399 d_types[i].name = NULL;
1401 d_systemMessages[i] = NULL;
1405 if (d_senders[i] != NULL) {
1406 delete[] d_senders[i];
1408 d_senders[i] = NULL;
1420 delete d_kcList->connection;
1422 while (d_anonList) {
1423 delete d_anonList->connection;
1438 p =
new knownConnection;
1442 strncpy(p->name, name, 1000);
1448 p->next = d_anonList;
1460 knownConnection **snitch)
1462 knownConnection *victim = *snitch;
1464 while (victim && (victim->connection != c)) {
1465 snitch = &((*snitch)->next);
1473 *snitch = victim->
next;
1481 for (p = d_kcList; p && strcmp(p->name, name); p = p->next) {
1487 return p->connection;
1490 vrpn_ConnectionManager::vrpn_ConnectionManager(
void)
1508 static int vrpn_getmyIP(
char *myIPchar,
unsigned maxlen,
1509 const char *NIC_IP = NULL,
1513 struct hostent *host;
1514 char myIPstring[100];
1516 if (myIPchar == NULL) {
1517 fprintf(stderr,
"vrpn_getmyIP: NULL pointer passed in\n");
1523 if (strlen(NIC_IP) > maxlen) {
1524 fprintf(stderr,
"vrpn_getmyIP: Name too long to return\n");
1528 fprintf(stderr,
"Was given IP address of %s so returning that.\n",
1531 strncpy(myIPchar, NIC_IP, maxlen);
1538 struct sockaddr_in socket_name;
1539 int socket_namelen =
sizeof(socket_name);
1541 if (getsockname(incoming_socket, (
struct sockaddr *)&socket_name,
1543 fprintf(stderr,
"vrpn_getmyIP: cannot get socket name.\n");
1547 sprintf(myIPstring,
"%u.%u.%u.%u",
1548 ntohl(socket_name.sin_addr.s_addr) >> 24,
1549 (ntohl(socket_name.sin_addr.s_addr) >> 16) & 0xff,
1550 (ntohl(socket_name.sin_addr.s_addr) >> 8) & 0xff,
1551 ntohl(socket_name.sin_addr.s_addr) & 0xff);
1554 if ((
unsigned)strlen(myIPstring) > maxlen) {
1555 fprintf(stderr,
"vrpn_getmyIP: Name too long to return\n");
1559 strcpy(myIPchar, myIPstring);
1562 fprintf(stderr,
"Decided on IP address of %s.\n", myIPchar);
1570 if (gethostname(myname,
sizeof(myname))) {
1571 fprintf(stderr,
"vrpn_getmyIP: Error finding local hostname\n");
1576 host = gethostbyname(myname);
1578 fprintf(stderr,
"vrpn_getmyIP: error finding host by name (%s)\n",
1585 if (host->h_length != 4) {
1586 fprintf(stderr,
"vrpn_getmyIP: Host length not 4\n");
1590 sprintf(myIPstring,
"%u.%u.%u.%u",
1591 (
unsigned int)(
unsigned char)host->h_addr_list[0][0],
1592 (
unsigned int)(
unsigned char)host->h_addr_list[0][1],
1593 (
unsigned int)(
unsigned char)host->h_addr_list[0][2],
1594 (
unsigned int)(
unsigned char)host->h_addr_list[0][3]);
1597 if ((
unsigned)strlen(myIPstring) > maxlen) {
1598 fprintf(stderr,
"vrpn_getmyIP: Name too long to return\n");
1602 strcpy(myIPchar, myIPstring);
1604 fprintf(stderr,
"Decided on IP address of %s.\n", myIPchar);
1616 fd_set *exceptfds,
struct timeval *timeout)
1618 fd_set tmpread, tmpwrite, tmpexcept;
1621 struct timeval timeout2;
1622 struct timeval *timeout2ptr;
1623 struct timeval start, stop, now;
1630 if ((timeout != NULL) &&
1631 ((timeout->tv_sec != 0) || (timeout->tv_usec != 0))) {
1632 timeout2 = *timeout;
1633 timeout2ptr = &timeout2;
1638 timeout2ptr = timeout;
1647 if (readfds != NULL) {
1653 if (writefds != NULL) {
1654 tmpwrite = *writefds;
1659 if (exceptfds != NULL) {
1660 tmpexcept = *exceptfds;
1663 FD_ZERO(&tmpexcept);
1667 ret = select(width, &tmpread, &tmpwrite, &tmpexcept, timeout2ptr);
1671 else if (errno != EINTR) {
1674 else if ((timeout != NULL) &&
1675 ((timeout->tv_sec != 0) || (timeout->tv_usec != 0))) {
1683 unsigned long usec_left;
1684 usec_left = (stop.tv_sec - now.tv_sec) * 1000000L;
1685 usec_left += stop.tv_usec - now.tv_usec;
1686 timeout2.tv_sec = usec_left / 1000000L;
1687 timeout2.tv_usec = usec_left % 1000000L;
1693 if (readfds != NULL) {
1696 if (writefds != NULL) {
1697 *writefds = tmpwrite;
1699 if (exceptfds != NULL) {
1700 *exceptfds = tmpexcept;
1719 #ifndef VRPN_USE_WINSOCK_SOCKETS 1729 ret = write(outfile, buffer + sofar, length - sofar);
1733 if ((ret == -1) && (errno == EINTR)) {
1738 }
while ((ret > 0) && (sofar < length));
1740 if (ret == -1)
return (-1);
1741 if (ret == 0)
return (0);
1772 ret = read(infile, buffer + sofar, length - sofar);
1776 if ((ret == -1) && (errno == EINTR)) {
1780 }
while ((ret > 0) && (sofar < length));
1782 if (ret == -1)
return (-1);
1783 if (ret == 0)
return (0);
1797 send(outsock, buffer + sofar, static_cast<int>(length - sofar), 0);
1799 if (nwritten == SOCKET_ERROR) {
1804 }
while (sofar < length);
1806 return static_cast<int>(sofar);
1825 recv(insock, buffer + sofar, static_cast<int>(length - sofar), 0);
1827 if (nread == SOCKET_ERROR) {
1835 }
while (sofar < length);
1837 return static_cast<int>(sofar);
1855 struct timeval *timeout)
1859 struct timeval timeout2;
1860 struct timeval *timeout2ptr;
1861 struct timeval start, stop, now;
1876 if ((timeout != NULL) &&
1877 ((timeout->tv_sec != 0) || (timeout->tv_usec != 0))) {
1878 timeout2 = *timeout;
1879 timeout2ptr = &timeout2;
1884 timeout2ptr = timeout;
1890 fd_set readfds, exceptfds;
1894 FD_SET(infile, &readfds);
1895 FD_ZERO(&exceptfds);
1896 FD_SET(infile, &exceptfds);
1898 NULL, &exceptfds, timeout2ptr);
1899 if (sel_ret == -1) {
1902 if (FD_ISSET(infile, &exceptfds)) {
1905 if (!FD_ISSET(infile, &readfds)) {
1906 if ((timeout != NULL) && (timeout->tv_sec == 0) &&
1907 (timeout->tv_usec == 0)) {
1908 return static_cast<int>(sofar);
1916 return static_cast<int>(sofar);
1923 if (!FD_ISSET(infile, &readfds)) {
1928 #ifndef VRPN_USE_WINSOCK_SOCKETS 1929 ret = read(infile, buffer + sofar, length - sofar);
1933 if ((ret == -1) && (errno == EINTR)) {
1940 nread = recv(infile, buffer + sofar,
1941 static_cast<int>(length - sofar), 0);
1947 }
while ((ret > 0) && (sofar < length));
1948 #ifndef VRPN_USE_WINSOCK_SOCKETS 1949 if (ret == -1)
return (-1);
1951 if (ret == 0)
return (0);
1953 return static_cast<int>(sofar);
1966 static SOCKET open_socket(
int type,
unsigned short *portno,
1967 const char *IPaddress)
1969 struct sockaddr_in name;
1970 struct hostent *phe;
1974 SOCKET sock = socket(AF_INET, type, 0);
1976 fprintf(stderr,
"open_socket: can't open socket.\n");
1978 fprintf(stderr,
" -- errno %d (%s).\n", errno, strerror(errno));
1985 vrpn_int32 optval = 1;
1986 vrpn_int32 sockoptsuccess =
1987 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval,
sizeof optval);
1988 fprintf(stderr,
"setsockopt returned %i, optval: %i\n", sockoptsuccess,
1992 namelen =
sizeof(name);
1995 memset((
void *)&name, 0, namelen);
1996 name.sin_family = AF_INET;
1998 name.sin_port = htons(*portno);
2001 name.sin_port = htons(0);
2006 name.sin_addr.s_addr = INADDR_ANY;
2008 else if ((name.sin_addr.s_addr = inet_addr(IPaddress)) == INADDR_NONE) {
2009 if ((phe = gethostbyname(IPaddress)) != NULL) {
2010 memcpy((
void *)&name.sin_addr, (
const void *)phe->h_addr,
2015 fprintf(stderr,
"open_socket: can't get %s host entry\n",
2023 fprintf(stderr,
"open_socket: request port %d, using NIC %d %d %d %d.\n",
2024 portno ? *portno : 0, ntohl(name.sin_addr.s_addr) >> 24,
2025 (ntohl(name.sin_addr.s_addr) >> 16) & 0xff,
2026 (ntohl(name.sin_addr.s_addr) >> 8) & 0xff,
2027 ntohl(name.sin_addr.s_addr) & 0xff);
2030 if (bind(sock, (
struct sockaddr *)&name, namelen) < 0) {
2031 fprintf(stderr,
"open_socket: can't bind address");
2033 fprintf(stderr,
" %d", *portno);
2036 fprintf(stderr,
" -- %d -- %s\n", errno, strerror(errno));
2038 fprintf(stderr,
" (This probably means that another application has " 2039 "the port open already)\n");
2045 if (getsockname(sock, (
struct sockaddr *)&name,
GSN_CAST & namelen)) {
2046 fprintf(stderr,
"vrpn: open_socket: cannot get socket name.\n");
2051 *portno = ntohs(name.sin_port);
2056 fprintf(stderr,
"open_socket: got port %d, using NIC %d %d %d %d.\n",
2057 portno ? *portno : ntohs(name.sin_port),
2058 ntohl(name.sin_addr.s_addr) >> 24,
2059 (ntohl(name.sin_addr.s_addr) >> 16) & 0xff,
2060 (ntohl(name.sin_addr.s_addr) >> 8) & 0xff,
2061 ntohl(name.sin_addr.s_addr) & 0xff);
2071 static SOCKET open_udp_socket(
unsigned short *portno,
const char *IPaddress)
2073 return open_socket(SOCK_DGRAM, portno, IPaddress);
2080 static SOCKET open_tcp_socket(
unsigned short *portno = NULL,
2081 const char *NIC_IP = NULL)
2083 return open_socket(SOCK_STREAM, portno, NIC_IP);
2090 static SOCKET vrpn_connect_udp_port(
const char *machineName,
int remotePort,
2091 const char *NIC_IP = NULL)
2094 struct sockaddr_in udp_name;
2095 struct hostent *remoteHost;
2098 udp_socket = open_udp_socket(NULL, NIC_IP);
2100 udp_namelen =
sizeof(udp_name);
2102 memset((
void *)&udp_name, 0, udp_namelen);
2103 udp_name.sin_family = AF_INET;
2111 if ((udp_name.sin_addr.s_addr = inet_addr(machineName)) == INADDR_NONE) {
2112 remoteHost = gethostbyname(machineName);
2117 u_long foo_mark = 0L;
2118 for (i = 0; i < 4; i++) {
2119 u_long one_char = remoteHost->h_addr_list[0][i];
2120 foo_mark = (foo_mark << 8) | one_char;
2122 udp_name.sin_addr.s_addr = foo_mark;
2124 memcpy(&(udp_name.sin_addr.s_addr), remoteHost->h_addr,
2125 remoteHost->h_length);
2131 "vrpn_connect_udp_port: error finding host by name (%s).\n",
2136 #ifndef VRPN_USE_WINSOCK_SOCKETS 2137 udp_name.sin_port = htons(remotePort);
2139 udp_name.sin_port = htons((u_short)remotePort);
2142 if (connect(udp_socket, (
struct sockaddr *)&udp_name, udp_namelen)) {
2143 fprintf(stderr,
"vrpn_connect_udp_port: can't bind udp socket.\n");
2149 udp_namelen =
sizeof(udp_name);
2150 if (getsockname(udp_socket, (
struct sockaddr *)&udp_name,
2152 fprintf(stderr,
"vrpn_connect_udp_port: cannot get socket name.\n");
2160 "vrpn_connect_udp_port: got port %d, using NIC %d %d %d %d.\n",
2161 ntohs(udp_name.sin_port), ntohl(udp_name.sin_addr.s_addr) >> 24,
2162 (ntohl(udp_name.sin_addr.s_addr) >> 16) & 0xff,
2163 (ntohl(udp_name.sin_addr.s_addr) >> 8) & 0xff,
2164 ntohl(udp_name.sin_addr.s_addr) & 0xff);
2192 static int get_local_socket_name(
char *local_host,
size_t max_length,
const char* remote_host)
2195 struct sockaddr_in udp_name;
2196 int udp_namelen =
sizeof(udp_name);
2198 SOCKET udp_socket = vrpn_connect_udp_port(remote_host, remote_port, NULL);
2200 fprintf(stderr,
"get_local_socket_name: cannot connect_udp_port to %s.\n", remote_host);
2201 fprintf(stderr,
" (returning 0.0.0.0 so we listen on all ports).\n");
2202 udp_name.sin_addr.s_addr = 0;
2204 if (getsockname(udp_socket, (
struct sockaddr *)&udp_name,
GSN_CAST & udp_namelen)) {
2205 fprintf(stderr,
"get_local_socket_name: cannot get socket name.\n");
2212 char myIPstring[100];
2213 int ret = sprintf(myIPstring,
"%d.%d.%d.%d",
2214 ntohl(udp_name.sin_addr.s_addr) >> 24,
2215 (ntohl(udp_name.sin_addr.s_addr) >> 16) & 0xff,
2216 (ntohl(udp_name.sin_addr.s_addr) >> 8) & 0xff,
2217 ntohl(udp_name.sin_addr.s_addr) & 0xff);
2220 if ((
unsigned)strlen(myIPstring) > max_length) {
2221 fprintf(stderr,
"get_local_socket_name: Name too long to return\n");
2225 strcpy(local_host, myIPstring);
2248 const char *machine,
2249 const int remote_port,
2250 const int local_port,
2251 const char *NIC_IP = NULL)
2264 if (vrpn_getmyIP(myIPchar,
sizeof(myIPchar), NIC_IP, udp_sock)) {
2266 "vrpn_udp_request_lob_packet: Error finding local hostIP\n");
2270 sprintf(msg,
"%s %d", myIPchar, local_port);
2271 msglen = static_cast<vrpn_int32>(strlen(msg) +
2275 if (send(udp_sock, msg, msglen, 0) == -1) {
2276 perror(
"vrpn_udp_request_lob_packet: send() failed");
2294 static int vrpn_get_a_TCP_socket(
SOCKET *listen_sock,
int *listen_portnum,
2295 const char *NIC_IP = NULL)
2297 struct sockaddr_in listen_name;
2300 listen_namelen =
sizeof(listen_name);
2305 *listen_sock = open_tcp_socket(NULL, NIC_IP);
2306 if (*listen_sock < 0) {
2307 fprintf(stderr,
"vrpn_get_a_TCP_socket: socket didn't open.\n");
2311 if (listen(*listen_sock, 1)) {
2312 fprintf(stderr,
"vrpn_get_a_TCP_socket: listen() failed.\n");
2317 if (getsockname(*listen_sock, (
struct sockaddr *)&listen_name,
2319 fprintf(stderr,
"vrpn_get_a_TCP_socket: cannot get socket name.\n");
2324 *listen_portnum = ntohs(listen_name.sin_port);
2344 static int vrpn_poll_for_accept(
SOCKET listen_sock,
SOCKET *accept_sock,
2345 double timeout = 0.0)
2352 FD_SET(listen_sock, &rfds);
2353 t.tv_sec = (long)(timeout);
2354 t.tv_usec = (long)((timeout - t.tv_sec) * 1000000L);
2357 perror(
"vrpn_poll_for_accept: select() failed");
2360 if (FD_ISSET(listen_sock, &rfds)) {
2363 if ((*accept_sock = accept(listen_sock, 0, 0)) == -1) {
2364 perror(
"vrpn_poll_for_accept: accept() failed");
2367 #if !defined(_WIN32_WCE) && !defined(__ANDROID__) 2369 struct protoent *p_entry;
2372 if ((p_entry = getprotobyname(
"TCP")) == NULL) {
2374 "vrpn_poll_for_accept: getprotobyname() failed.\n");
2379 if (setsockopt(*accept_sock, p_entry->p_proto, TCP_NODELAY,
2380 SOCK_CAST & nonzero,
sizeof(nonzero)) == -1) {
2381 perror(
"vrpn_poll_for_accept: setsockopt() failed");
2406 static int vrpn_start_server(
const char *machine,
char *server_name,
char *args,
2407 const char *IPaddress = NULL)
2409 #if defined(VRPN_USE_WINSOCK_SOCKETS) || defined(__CYGWIN__) 2410 fprintf(stderr,
"VRPN: vrpn_start_server not ported" 2411 " for windows winsocks or cygwin!\n");
2412 IPaddress = IPaddress;
2414 server_name = server_name;
2424 if (vrpn_get_a_TCP_socket(&server_sock, &PortNum, IPaddress)) {
2425 fprintf(stderr,
"vrpn_start_server: Cannot get listen socket\n");
2429 if ((pid = fork()) == -1) {
2430 fprintf(stderr,
"vrpn_start_server: cannot fork().\n");
2437 int num_descriptors;
2442 if (vrpn_getmyIP(myIPchar,
sizeof(myIPchar), IPaddress, server_sock)) {
2443 fprintf(stderr,
"vrpn_start_server: Error finding my IP\n");
2450 num_descriptors = getdtablesize();
2451 for (loop = 0; loop < num_descriptors; loop++) {
2452 if ((loop != 1) && (loop != 2)) {
2461 if ((rsh_to_use = (
char *)getenv(
"VRPN_RSH")) == NULL) {
2464 sprintf(command,
"%s %s %s %s -client %s %d", rsh_to_use, machine,
2465 server_name, args, myIPchar, PortNum);
2466 ret = system(command);
2467 if ((ret == 127) || (ret == -1)) {
2468 fprintf(stderr,
"vrpn_start_server: system() failed !!!!!\n");
2470 fprintf(stderr,
"Attempted command was: '%s'\n", command);
2486 for (waitloop = 0; waitloop < (
SERVCOUNT); waitloop++) {
2492 ret = vrpn_poll_for_accept(server_sock, &child_socket,
SERVWAIT);
2494 fprintf(stderr,
"vrpn_start_server: Accept poll failed\n");
2503 deadkid = wait3(&status, WNOHANG, NULL);
2504 if (deadkid == pid) {
2505 fprintf(stderr,
"vrpn_start_server: server process exited\n");
2512 "vrpn_start_server: server failed to connect in time\n");
2513 fprintf(stderr,
" (took more than %d seconds)\n",
2522 return (child_socket);
2547 static_cast<char>(remote_log_mode +
'0'));
2569 bp = strrchr(buffer,
'.');
2572 fprintf(stderr,
"check_vrpn_cookie: " 2573 "bad cookie (wanted '%s', got '%s'\n",
2580 "check_vrpn_cookie(): " 2581 "VRPN Note: minor version number doesn't match: (prefer '%s', " 2582 "got '%s'). This is not normally a problem.\n",
2606 bp = strrchr(buffer,
'.');
2607 int majorComparison = strncmp(
2609 if (majorComparison > 0 ||
2612 fprintf(stderr,
"check_vrpn_file_cookie: " 2613 "bad cookie (wanted >='%s' and <='%s', " 2620 fprintf(stderr,
"check_vrpn_file_cookie(): " 2621 "Note: Version number doesn't match: (prefer '%s', got " 2622 "'%s'). This is not normally a problem.\n",
2635 vrpn_int32 *connectedEndpointCounter)
2637 , d_remoteLogMode(0)
2638 , d_remoteInLogName(NULL)
2639 , d_remoteOutLogName(NULL)
2644 , d_dispatcher(dispatcher)
2645 , d_connectionCounter(connectedEndpointCounter)
2651 vrpn_int32 *connectedEndpointCounter)
2655 , d_tcpListenPort(0)
2657 , d_remote_machine_name(NULL)
2658 , d_remote_port_number(0)
2659 , d_tcp_only(vrpn_FALSE)
2668 , d_tcpSequenceNumber(0)
2669 , d_udpSequenceNumber(0)
2670 , d_tcpInbuf((char *)d_tcpAlignedInbuf)
2671 , d_udpInbuf((char *)d_udpAlignedInbuf)
2672 , d_NICaddress(NULL)
2757 return d_types->mapToLocalID(remote_type);
2762 return d_senders->mapToLocalID(remote_sender);
2784 fprintf(stderr,
"vrpn_Endpoint::init: Out of memory!\n");
2791 fprintf(stderr,
"vrpn_Endpoint::init: Out of memory!\n");
2798 fprintf(stderr,
"vrpn_Endpoint::init: Out of memory!\n");
2819 fd_set readfds, exceptfds;
2820 int tcp_messages_read;
2821 int udp_messages_read;
2823 bool time_to_try_again =
false;
2837 FD_ZERO(&exceptfds);
2855 fprintf(stderr,
"vrpn_Endpoint::mainloop: select failed.\n");
2857 fprintf(stderr,
" Errno (%d): %s.\n", errno, strerror(errno));
2867 fprintf(stderr,
"vrpn_Endpoint::mainloop: Exception on socket\n");
2876 if (udp_messages_read == -1) {
2877 fprintf(stderr,
"vrpn_Endpoint::mainloop: " 2878 "UDP handling failed, dropping connection\n");
2883 if (udp_messages_read != 0)
2884 printf(
"udp message read = %d\n", udp_messages_read);
2891 if (tcp_messages_read == -1) {
2892 fprintf(stderr,
"vrpn: TCP handling failed, dropping " 2893 "connection (this is normal when a connection " 2900 if (tcp_messages_read) {
2901 printf(
"tcp_message_read %d bytes\n", tcp_messages_read);
2919 printf(
"TRYING_TO_CONNECT\n");
2926 time_to_try_again =
true;
2932 if (time_to_try_again) {
2938 fprintf(stderr,
"vrpn_Endpoint::mainloop: " 2939 "Can't set up new connection!\n");
2951 fprintf(stderr,
"vrpn_Endpoint: mainloop: Can't poll for accept\n");
2958 printf(
"vrpn: Connection established\n");
2963 fprintf(stderr,
"vrpn_Endpoint: mainloop: " 2964 "Can't set up new connection!\n");
2976 if (time_to_try_again) {
2993 "vrpn_Endpoint: mainloop: Can't lob UDP request\n");
3009 fprintf(stderr,
"vrpn_Endpoint::mainloop(): " 3010 "Unknown status (%d)\n",
3034 return d_senders->addLocalID(name, which);
3043 return d_types->addLocalID(name, which);
3048 vrpn_int32 local_id)
3050 return d_types->addRemoteEntry(type_name, remote_id, local_id);
3055 vrpn_int32 local_id)
3057 return d_senders->addRemoteEntry(sender_name, remote_id, local_id);
3076 vrpn_int32 type, vrpn_int32 sender,
3078 vrpn_uint32 class_of_service)
3091 fprintf(stderr,
"vrpn_Endpoint::pack_message: " 3092 "Couldn't log outgoing message.!\n");
3104 fprintf(stderr,
"vrpn_Endpoint::pack_message: " 3105 "Not connected, so throwing out message.\n");
3140 return (!ret) ? -1 : 0;
3145 vrpn_int32 ret, sent = 0;
3152 "vrpn_Endpoint::send_pending_reports(): No TCP connection\n");
3161 timeout.tv_usec = 0;
3168 NULL, &f, &timeout);
3170 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports(): " 3171 "select() failed.\n");
3172 #ifdef VRPN_USE_WINSOCK_SOCKETS 3175 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
3176 FORMAT_MESSAGE_MAX_WIDTH_MASK,
3177 NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
3178 (LPSTR)Message, 1024, NULL);
3179 fprintf(stderr,
"Windows Sockets Error (%d): %s.\n", WSAGetLastError(),
3182 fprintf(stderr,
"Errno (%d): %s.\n", errno, strerror(errno));
3198 printf(
"TCP Sent %d bytes\n", ret);
3201 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports: " 3202 "TCP send failed.\n");
3218 printf(
"UDP Sent %d bytes\n", ret);
3221 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports: " 3222 " UDP send failed.");
3242 vrpn_uint32 portparam = portno;
3243 char myIPchar[1000];
3247 fprintf(stderr,
"Getting IP address of NIC %s.\n",
d_NICaddress);
3256 perror(
"vrpn_Endpoint::pack_udp_description: can't get host name");
3266 fprintf(stderr,
"vrpn_Endpoint::pack_udp_description: " 3267 "Packing UDP %s:%d\n",
3272 return pack_message(static_cast<vrpn_uint32>(strlen(myIPchar)) + 1, now,
3283 const char *inName =
"";
3284 const char *outName =
"";
3294 2 *
sizeof(vrpn_int32) + strlen(inName) + 1 + strlen(outName) + 1;
3295 char *buf =
new char[bufsize];
3298 "vrpn_Endpoint::pack_log_description(): Out of memory\n");
3317 vrpn_int32 bufleft = static_cast<vrpn_int32>(bufsize);
3318 vrpn_buffer(bp, &bufleft, (vrpn_int32)strlen(inName));
3319 vrpn_buffer(bp, &bufleft, (vrpn_int32)strlen(outName));
3320 vrpn_buffer(bp, &bufleft, inName, static_cast<vrpn_int32>(strlen(inName)));
3323 static_cast<vrpn_int32>(strlen(outName)));
3325 int ret =
pack_message(static_cast<vrpn_uint32>(bufsize - bufleft), now,
3338 timeval localTimeout;
3339 fd_set readfds, exceptfds;
3340 unsigned num_messages_read = 0;
3345 printf(
"vrpn_Endpoint::handle_tcp_messages() called\n");
3349 localTimeout.tv_sec = timeout->tv_sec;
3350 localTimeout.tv_usec = timeout->tv_usec;
3353 localTimeout.tv_sec = 0;
3354 localTimeout.tv_usec = 0;
3367 FD_ZERO(&exceptfds);
3371 NULL, &exceptfds, &localTimeout);
3372 if (sel_ret == -1) {
3373 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: " 3380 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: " 3381 "Exception on socket\n");
3394 num_messages_read++;
3406 return num_messages_read;
3423 timeval localTimeout;
3424 fd_set readfds, exceptfds;
3425 unsigned num_messages_read = 0;
3430 printf(
"vrpn_Endpoint::handle_udp_messages() called\n");
3434 localTimeout.tv_sec = timeout->tv_sec;
3435 localTimeout.tv_usec = timeout->tv_usec;
3438 localTimeout.tv_sec = 0;
3439 localTimeout.tv_usec = 0;
3451 FD_ZERO(&exceptfds);
3455 &readfds, NULL, &exceptfds, &localTimeout);
3456 if (sel_ret == -1) {
3457 perror(
"vrpn_Endpoint::handle_udp_messages: select failed()");
3463 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_udp_messages: " 3464 "Exception on socket\n");
3476 if (inbuf_len == -1) {
3477 fprintf(stderr,
"vrpn_Endpoint::handle_udp_message: " 3478 "recv() failed.\n");
3487 inbuf_len -= retval;
3488 inbuf_ptr += retval;
3492 num_messages_read++;
3506 return num_messages_read;
3521 if (sscanf(msg,
"%s %d", machine, &port) != 2) {
3530 struct sockaddr_in client;
3531 struct hostent *host;
3536 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: " 3537 "can't open socket\n");
3540 client.sin_family = AF_INET;
3548 if ((client.sin_addr.s_addr = inet_addr(addr)) == INADDR_NONE) {
3549 host = gethostbyname(addr);
3555 u_long foo_mark = 0;
3556 for (i = 0; i < 4; i++) {
3557 u_long one_char = host->h_addr_list[0][i];
3558 foo_mark = (foo_mark << 8) | one_char;
3560 client.sin_addr.s_addr = foo_mark;
3563 memcpy(&(client.sin_addr.s_addr), host->h_addr, host->h_length);
3568 #if !defined(hpux) && !defined(__hpux) && !defined(_WIN32) && !defined(sparc) 3569 herror(
"gethostbyname error:");
3571 perror(
"gethostbyname error:");
3573 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: " 3574 "error finding host by name (%s)\n",
3580 #ifndef VRPN_USE_WINSOCK_SOCKETS 3581 client.sin_port = htons(port);
3583 client.sin_port = htons((u_short)port);
3586 if (connect(
d_tcpSocket, (
struct sockaddr *)&client,
sizeof(client)) < 0) {
3587 #ifdef VRPN_USE_WINSOCK_SOCKETS 3589 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: Could not connect " 3590 "to machine %d.%d.%d.%d port %d\n",
3591 (
int)(client.sin_addr.S_un.S_un_b.s_b1),
3592 (
int)(client.sin_addr.S_un.S_un_b.s_b2),
3593 (
int)(client.sin_addr.S_un.S_un_b.s_b3),
3594 (
int)(client.sin_addr.S_un.S_un_b.s_b4),
3595 (
int)(ntohs(client.sin_port)));
3596 int error = WSAGetLastError();
3597 fprintf(stderr,
"Winsock error: %d\n", error);
3600 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: Could not connect to " 3601 "machine %d.%d.%d.%d port %d\n",
3602 (
int)((client.sin_addr.s_addr >> 24) & 0xff),
3603 (
int)((client.sin_addr.s_addr >> 16) & 0xff),
3604 (
int)((client.sin_addr.s_addr >> 8) & 0xff),
3605 (
int)((client.sin_addr.s_addr >> 0) & 0xff),
3606 (
int)(ntohs(client.sin_port)));
3614 #if !defined(_WIN32_WCE) && !defined(__ANDROID__) 3616 struct protoent *p_entry;
3619 if ((p_entry = getprotobyname(
"TCP")) == NULL) {
3622 "vrpn_Endpoint::connect_tcp_to: getprotobyname() failed.\n");
3628 if (setsockopt(
d_tcpSocket, p_entry->p_proto, TCP_NODELAY,
3629 SOCK_CAST & nonzero,
sizeof(nonzero)) == -1) {
3630 perror(
"vrpn_Endpoint::connect_tcp_to: setsockopt() failed");
3647 fprintf(stderr,
"vrpn_Endpoint::connect_udp_to: " 3648 "Couldn't open outbound UDP link.\n");
3660 if (bytecount < 0) {
3664 new_outbuf =
new char[bytecount];
3722 fprintf(stderr,
"vrpn_Endpoint::drop_connection: Can't log\n");
3737 (*d_connectionCounter)--;
3764 fprintf(stderr,
"Setting endpoint NIC address to %s.\n", address);
3773 fprintf(stderr,
"vrpn_Endpoint::setNICaddress: Out of memory.\n");
3788 perror(
"vrpn_Endpoint::setup_new_connection: " 3789 "Internal error - array too small. The code's broken.");
3799 fprintf(stderr,
"vrpn_Endpoint::setup_new_connection: " 3800 "Can't write cookie.\n");
3816 timeout = *pTimeout;
3820 timeout.tv_usec = 0;
3823 fd_set readfds, exceptfds;
3832 FD_ZERO(&exceptfds);
3842 &exceptfds, &timeout) == -1) {
3843 fprintf(stderr,
"vrpn_Endpoint::poll_for_cookie(): select failed.\n");
3851 "vrpn_Endpoint::poll_for_cookie(): Exception on socket\n");
3860 "vrpn_Endpoint::poll_for_cookie: cookie handling failed\n" 3861 " while connecting to \"%s\"\n",
3867 printf(
"vrpn_Endpoint::poll_for_cookie() got cookie\n");
3877 char *recvbuf =
new char[sendlen];
3878 if (recvbuf == NULL) {
3879 fprintf(stderr,
"vrpn_Endpoint_IP::finish_new_connection_setup(): Out " 3880 "of memory when allocating receiver buffer\n");
3887 if (ret != sendlen) {
3888 perror(
"vrpn_Endpoint::finish_new_connection_setup: Can't read cookie");
3911 if ((received_logmode < 0) ||
3913 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: " 3914 "Got invalid log mode %d\n",
3915 static_cast<int>(received_logmode));
3932 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: " 3933 "Can't pack remote logging instructions.\n");
3947 unsigned short udp_portnum = static_cast<unsigned short>(INADDR_ANY);
3950 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: " 3951 "can't open UDP socket\n");
3959 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: " 3960 "Can't pack UDP msg\n");
3970 "CONNECTED - vrpn_Endpoint::finish_new_connection_setup.\n");
3987 "vrpn_Endpoint::finish_new_connection_setup: Can't send UDP msg\n");
4013 (*d_connectionCounter)++;
4022 vrpn_int32 header[5];
4023 struct timeval time;
4024 vrpn_int32 sender, type;
4025 size_t len, payload_len, ceil_len;
4030 "vrpn_Endpoint::handle_tcp_messages(): something to read\n");
4036 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: " 4037 "Can't read header (this is normal when a connection " 4041 len = ntohl(header[0]);
4042 time.tv_sec = ntohl(header[1]);
4043 time.tv_usec = ntohl(header[2]);
4044 sender = ntohl(header[3]);
4045 type = ntohl(header[4]);
4047 fprintf(stderr,
" header: Len %d, Sender %d, Type %d\n", (
int)len,
4048 (
int)sender, (
int)type);
4052 vrpn_int32 header_len =
sizeof(header);
4056 if (header_len > static_cast<vrpn_int32>(
sizeof(header))) {
4060 header_len -
sizeof(header)) !=
4061 (int)(header_len -
sizeof(header))) {
4062 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: " 4063 "Can't read header + alignment\n");
4071 payload_len = len - header_len;
4072 ceil_len = payload_len;
4079 if (buflen < ceil_len) {
4081 "vrpn: vrpn_Endpoint::handle_tcp_messages: Message too long\n");
4087 perror(
"vrpn: vrpn_Endpoint::handle_tcp_messages: Can't read body");
4092 fprintf(stderr,
"Couldn't log incoming message.!\n");
4096 retval =
dispatch(type, sender, time, static_cast<vrpn_uint32>(payload_len),
4107 vrpn_int32 header[5];
4108 struct timeval time;
4109 vrpn_int32 sender, type;
4110 vrpn_uint32 len, payload_len, ceil_len;
4115 vrpn_uint32 header_len =
sizeof(header);
4120 if (header_len > (vrpn_uint32)inbuf_len) {
4121 fprintf(stderr,
"vrpn_Endpoint::getOneUDPMessage: Can't read header");
4124 memcpy(header, inbuf_ptr,
sizeof(header));
4125 inbuf_ptr += header_len;
4126 len = ntohl(header[0]);
4127 time.tv_sec = ntohl(header[1]);
4128 time.tv_usec = ntohl(header[2]);
4129 sender = ntohl(header[3]);
4130 type = ntohl(header[4]);
4133 fprintf(stderr,
"Message type %ld (local type %ld), sender %ld received\n",
4135 fprintf(stderr,
"Message length is %d (buffer length %d).\n", len,
4142 payload_len = len - header_len;
4143 ceil_len = payload_len;
4149 if (header_len + ceil_len > (vrpn_uint32)inbuf_len) {
4150 fprintf(stderr,
"vrpn_Endpoint::getOneUDPMessage: Can't read payload");
4156 fprintf(stderr,
"Couldn't log incoming message.!\n");
4160 retval =
dispatch(type, sender, time, payload_len, inbuf_ptr);
4165 return ceil_len + header_len;
4169 vrpn_uint32 payload_len,
char *bufptr)
4181 payload_len, bufptr)) {
4188 if (
d_dispatcher->doSystemCallbacksFor(type, sender, time, payload_len,
4190 fprintf(stderr,
"vrpn_Endpoint::dispatch: " 4191 "Nonzero system return\n");
4200 vrpn_int32 &numOut, vrpn_uint32 len,
4201 timeval time, vrpn_int32 type,
4202 vrpn_int32 sender,
const char *buffer,
4203 vrpn_uint32 sequenceNumber)
4208 buffer, sequenceNumber);
4218 sender, buffer, sequenceNumber);
4236 vrpn_uint32 outbuf_size,
4237 vrpn_uint32 initial_out,
4239 struct timeval time,
4245 vrpn_uint32 ceil_len, header_len, total_len;
4246 vrpn_uint32 curr_out = initial_out;
4257 header_len = 5 *
sizeof(vrpn_int32);
4261 total_len = header_len + ceil_len;
4262 if ((curr_out + total_len) > (vrpn_uint32)outbuf_size) {
4276 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(header_len + len);
4277 curr_out +=
sizeof(vrpn_uint32);
4281 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(time.tv_sec);
4282 curr_out +=
sizeof(vrpn_uint32);
4283 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(time.tv_usec);
4284 curr_out +=
sizeof(vrpn_uint32);
4287 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(sender);
4288 curr_out +=
sizeof(vrpn_uint32);
4289 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(type);
4290 curr_out +=
sizeof(vrpn_uint32);
4295 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(seqNo);
4296 curr_out +=
sizeof(vrpn_uint32);
4299 curr_out = initial_out + header_len;
4304 if (buffer != NULL) {
4305 memcpy(&outbuf[curr_out], buffer, len);
4307 curr_out += ceil_len;
4309 printf(
"Marshalled: len %d, ceil_len %d: '", len, ceil_len);
4312 return curr_out - initial_out;
4318 vrpn_Endpoint *endpoint = static_cast<vrpn_Endpoint *>(userdata);
4321 vrpn_int32 local_id;
4324 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_type_message: " 4325 "Type name too long\n");
4330 strncpy(type_name, p.
buffer +
sizeof(vrpn_int32),
4335 i = ntohl(*((vrpn_int32 *)p.
buffer));
4336 type_name[i] =
'\0';
4339 printf(
"Registering other-side type: '%s'\n", type_name);
4342 local_id = endpoint->
d_dispatcher->getTypeID(type_name);
4344 if (local_id == -1) {
4350 printf(
"vrpn_Endpoint::handle_type_message: NULL d_parent " 4351 "when trying to auto-register remote message type %s.\n",
4357 fprintf(stderr,
"vrpn: Failed to add remote type %s\n", type_name);
4366 if (inName != NULL) {
4369 if (outName != NULL) {
4390 vrpn_Endpoint *endpoint = static_cast<vrpn_Endpoint *>(userdata);
4393 vrpn_int32 local_id;
4396 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_sender_message():Sender " 4402 strncpy(sender_name, p.
buffer +
sizeof(vrpn_int32),
4407 i = ntohl(*((vrpn_int32 *)p.
buffer));
4408 sender_name[i] =
'\0';
4411 printf(
"Registering other-side sender: '%s'\n", sender_name);
4414 local_id = endpoint->
d_dispatcher->getSenderID(sender_name);
4416 if (local_id == -1) {
4422 printf(
"vrpn_Endpoint::handle_sender_message: NULL d_parent " 4423 "when trying to auto-register remote message sender %s\n",
4429 fprintf(stderr,
"vrpn: Failed to add remote sender %s\n", sender_name);
4442 static_cast<vrpn_int32>(strlen(
d_dispatcher->typeName(which)) + 1);
4444 char buffer[
sizeof(len) +
sizeof(
cName)];
4446 netlen = htonl(len);
4453 printf(
" vrpn_Connection: Packing type '%s', %d\n",
4456 memcpy(buffer, &netlen,
sizeof(netlen));
4457 memcpy(&buffer[
sizeof(len)],
d_dispatcher->typeName(which),
4461 return pack_message((vrpn_uint32)(len +
sizeof(len)), now,
4472 static_cast<vrpn_int32>(strlen(
d_dispatcher->senderName(which)) + 1);
4474 char buffer[
sizeof(len) +
sizeof(
cName)];
4476 netlen = htonl(len);
4483 printf(
" vrpn_Connection: Packing sender '%s'\n",
4486 memcpy(buffer, &netlen,
sizeof(netlen));
4487 memcpy(&buffer[
sizeof(len)],
d_dispatcher->senderName(which),
4491 return pack_message((vrpn_uint32)(len +
sizeof(len)), now,
4496 static int flush_udp_socket(
SOCKET fd)
4498 timeval localTimeout;
4499 fd_set readfds, exceptfds;
4505 localTimeout.tv_sec = 0;
4506 localTimeout.tv_usec = 0;
4514 FD_ZERO(&exceptfds);
4515 FD_SET(fd, &readfds);
4516 FD_SET(fd, &exceptfds);
4518 &exceptfds, &localTimeout);
4519 if (sel_ret == -1) {
4520 fprintf(stderr,
"flush_udp_socket: select failed().");
4525 if (FD_ISSET(fd, &exceptfds)) {
4526 fprintf(stderr,
"flush_udp_socket: Exception on socket.\n");
4531 if (FD_ISSET(fd, &readfds)) {
4534 inbuf_len = recv(fd, buf, 10000, 0);
4535 if (inbuf_len == -1) {
4536 fprintf(stderr,
"flush_udp_socket: recv() failed.\n");
4585 vrpn_int32 inNameLen, outNameLen;
4586 const char **bp = &p.
buffer;
4595 endpoint->
setLogNames(inNameLen == 0 ? NULL : *bp,
4596 outNameLen == 0 ? NULL : *bp + inNameLen + 1);
4597 if (inNameLen > 0) retval = endpoint->
d_inLog->
open();
4598 if (outNameLen > 0) retval = endpoint->
d_outLog->
open();
4613 fprintf(stderr,
"vrpn_Connection::handle_log_message: " 4614 "Remote connection requested logging.\n");
4633 vrpn_int32 type, vrpn_int32 sender,
4635 vrpn_uint32 class_of_service)
4641 printf(
"vrpn_Connection::pack_message: Can't pack because the " 4642 "connection is broken\n");
4648 printf(
"vrpn_Connection::pack_message: bad type (%d)\n", type);
4654 if ((sender < 0) || (sender >=
d_dispatcher->numSenders())) {
4655 printf(
"vrpn_Connection::pack_message: bad sender (%d)\n", sender);
4668 class_of_service) != 0)) {
4738 int final_retval = 0;
4743 return final_retval;
4825 const char *local_out_logfile_name,
4829 , d_numConnectedEndpoints(0)
4831 , d_autoDeleteStatus(false)
4832 , d_dispatcher(NULL)
4833 , d_serverLogCount(0)
4837 , d_serverLogName(NULL)
4838 , d_endpointAllocator(epa)
4839 , d_updateEndpoint(vrpn_FALSE)
4851 if (local_out_logfile_name) {
4852 d_endpoints[0] = (*d_endpointAllocator)(
this, NULL);
4854 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d " 4855 "Couldn't create endpoint for log file.\n",
4867 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d " 4868 "Couldn't open outgoing log file.\n",
4885 if (local_in_logfile_name) {
4888 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d " 4899 const char *local_in_logfile_name,
const char *local_out_logfile_name,
4900 const char *remote_in_logfile_name,
const char *remote_out_logfile_name,
4902 : connectionStatus(
BROKEN)
4905 , d_numConnectedEndpoints(0)
4907 , d_autoDeleteStatus(false)
4908 , d_dispatcher(NULL)
4909 , d_serverLogCount(0)
4911 , d_serverLogName(NULL)
4912 , d_endpointAllocator(epa)
4913 , d_updateEndpoint(vrpn_FALSE)
4926 fprintf(stderr,
"vrpn_Connection:%d Out of memory.\n", __LINE__);
4936 (((remote_in_logfile_name && strlen(remote_in_logfile_name) > 0)
4939 ((remote_out_logfile_name && strlen(remote_out_logfile_name) > 0)
4942 if (!remote_in_logfile_name) {
4948 new char[strlen(remote_in_logfile_name) + 1];
4952 if (!remote_out_logfile_name) {
4958 new char[strlen(remote_out_logfile_name) + 1];
4965 if (local_in_logfile_name && (strlen(local_in_logfile_name) != 0)) {
4970 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d " 4971 "Couldn't open incoming log file.\n",
4980 if (local_out_logfile_name && (strlen(local_out_logfile_name) != 0)) {
4985 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d " 4986 "Couldn't open local outgoing log file.\n",
5005 if (d_references > 0) {
5007 "Connection was deleted while %d references still remain.\n",
5023 if (d_references == 0 && d_autoDeleteStatus ==
true) {
5026 else if (d_references < 0) {
5028 fprintf(stderr,
"Negative reference count. This shouldn't happen.");
5038 fprintf(stderr,
"vrpn_Connection::register_sender: " 5039 "%d senders; new name \"%s\"\n",
5047 fprintf(stderr,
"Sender already defined as id %d.\n", retval);
5055 fprintf(stderr,
"Packing sender description for %s, type %d.\n", name,
5080 fprintf(stderr,
"vrpn_Connection::register_message_type: " 5081 "%d type; new name \"%s\"\n",
5089 fprintf(stderr,
"Type already defined as id %d.\n", retval);
5101 fprintf(stderr,
"Packing type description for %s, type %d.\n", name,
5122 struct timeval time,
5123 vrpn_uint32 payload_len,
const char *buf)
5125 return d_dispatcher->doCallbacksFor(type, sender, time, payload_len, buf);
5134 char **local_out_logname,
5135 char **remote_in_logname,
5136 char **remote_out_logname)
5143 if (local_in_logname != NULL)
5145 if (local_out_logname != NULL)
5148 if (remote_in_logname != NULL) {
5150 *remote_in_logname =
5155 *remote_in_logname = NULL;
5159 if (remote_out_logname != NULL) {
5161 *remote_out_logname =
5166 *remote_out_logname = NULL;
5176 vrpn_int32 *connectedEC)
5192 printf(
"Just read disconnect message from logfile\n");
5201 void *userdata, vrpn_int32 sender)
5203 return d_dispatcher->addHandler(type, handler, userdata, sender);
5208 void *userdata, vrpn_int32 sender)
5210 return d_dispatcher->removeHandler(type, handler, userdata, sender);
5227 for (endpointIndex = 0; endpointIndex <
d_numEndpoints; endpointIndex++) {
5241 for (endpointIndex = 0; endpointIndex <
d_numEndpoints; endpointIndex++) {
5278 const char *cname,
const char *local_in_logfile_name,
5279 const char *local_out_logfile_name,
const char *remote_in_logfile_name,
5280 const char *remote_out_logfile_name,
const char *NIC_IPaddress,
5281 bool force_connection)
5283 if (cname == NULL) {
5284 fprintf(stderr,
"vrpn_get_connection_by_name(): NULL name\n");
5290 const char *where_at;
5291 if ((where_at = strrchr(cname,
'@')) != NULL) {
5292 cname = where_at + 1;
5296 if (!force_connection) {
5308 int is_file = !strncmp(cname,
"file:", 5);
5312 local_out_logfile_name);
5316 cname, port, local_in_logfile_name, local_out_logfile_name,
5317 remote_in_logfile_name, remote_out_logfile_name, NIC_IPaddress);
5324 fprintf(stderr,
"Could not create new connection.");
5359 const char *local_in_logfile_name,
5360 const char *local_out_logfile_name)
5365 if (cname == NULL) {
5366 fprintf(stderr,
"vrpn_create_server_connection(): NULL name\n");
5370 if (location == NULL) {
5373 int is_loopback = !strncmp(cname,
"loopback:", 9);
5374 int is_mpi = !strncmp(cname,
"mpi:", 4);
5377 XXX_implement_MPI_server_connection;
5379 fprintf(stderr,
"vrpn_create_server_connection(): MPI support not " 5380 "compiled in. Set VRPN_USE_MPI in vrpn_Configure.h " 5381 "and recompile.\n");
5385 }
else if (is_loopback) {
5394 if (strlen(location) == 0) {
5396 local_in_logfile_name,
5397 local_out_logfile_name);
5405 if (strlen(machine) == 0) {
5409 unsigned short port =
5412 local_out_logfile_name, machine);
5421 fprintf(stderr,
"vrpn_create_server_connection(): Could not create new " 5454 fprintf(stderr,
"vrpn_Connection_IP::connect_to_client:" 5455 " Too many existing connections.\n");
5466 fprintf(stderr,
"vrpn_Connection_IP::connect_to_client:" 5467 " Out of memory on new endpoint\n");
5472 sprintf(msg,
"%s %d", machine, port);
5473 printf(
"vrpn_Connection_IP::connect_to_client: " 5474 "Connection request received: %s\n",
5497 fprintf(stderr,
"vrpn_Connection_IP::handle_connection(): " 5498 "Can't set up new connection!\n");
5512 char rhostname[1000];
5515 printf(
" Received request for UDP channel to %s\n", p.
buffer);
5519 strncpy(rhostname, p.
buffer,
sizeof(rhostname));
5520 rhostname[
sizeof(rhostname) - 1] =
'\0';
5537 printf(
" Opened UDP channel to %s:%d\n", rhostname, p.
sender);
5548 fprintf(stderr,
"vrpn_Connection_IP::send_pending_reports: " 5549 "Closing failed endpoint.\n");
5562 #ifdef VRPN_USE_WINSOCK_SOCKETS 5569 winStatus = WSAStartup(MAKEWORD(1, 1), &wsaData);
5571 fprintf(stderr,
"vrpn_Connection_IP::init(): " 5572 "Failed to set up sockets.\n");
5573 fprintf(stderr,
"WSAStartup failed with error code %d\n", winStatus);
5576 #endif // windows sockets 5584 #ifndef _WIN32 // XXX what about cygwin? 5586 signal(SIGPIPE, (
void (*)(
int))SIG_IGN);
5588 signal(SIGPIPE, SIG_IGN);
5611 const struct timeval *pTimeout)
5621 timeout = *pTimeout;
5625 timeout.tv_usec = 0;
5636 if (request == -1) {
5638 "vrpn_Connection_IP::server_check_for_incoming_connections(): " 5639 "select failed.\n");
5645 else if (request != 0) {
5646 struct sockaddr_in from;
5647 int fromlen =
sizeof(from);
5651 (
struct sockaddr *)&from,
GSN_CAST & fromlen) == -1) {
5653 "vrpn: Error on recvfrom: Bad connection attempt\n");
5658 msg[
sizeof(msg) - 1] =
'\0';
5664 char fromname[1024];
5665 unsigned long addr_num = ntohl(from.sin_addr.s_addr);
5666 sprintf(fromname,
"%lu.%lu.%lu.%lu", (addr_num) >> 24,
5667 (addr_num >> 16) & 0xff, (addr_num >> 8) & 0xff,
5669 printf(
"vrpn: Connection request received from %s: %s\n", fromname,
5680 char *checkHost =
new char[strlen(msg) + 1];
5682 if (checkHost == NULL) {
5684 "server_check_for_incoming_connections(): Out of memory\n");
5687 if (sscanf(msg,
"%s %d", checkHost, &checkPort) != 2) {
5690 "server_check_for_incoming_connections(): Malformed request\n");
5694 if (checkPort < 1024) {
5696 "server_check_for_incoming_connections(): Bad port\n");
5703 for (checkLoop = 0; checkLoop < strlen(checkHost); checkLoop++) {
5704 char checkChar = checkHost[checkLoop];
5705 if (!isalnum(checkChar) && (checkChar !=
'.')) {
5708 "server_check_for_incoming_connections(): Bad hostname\n");
5717 fprintf(stderr,
"vrpn: Too many existing connections; " 5718 "ignoring request from %s\n",
5733 "vrpn_Connection_IP::server_check_for_incoming_connections:\n" 5734 " Out of memory on new endpoint\n");
5749 fprintf(stderr,
"vrpn_Connection_IP::server_check_for_incoming_" 5751 "Couldn't open log file.\n");
5769 sscanf(msg,
"%*s %d", &port);
5793 fprintf(stderr,
"Error accepting on TCP socket.\n");
5798 printf(
"vrpn: TCP connection request received.\n");
5801 fprintf(stderr,
"vrpn: Too many existing connections; " 5802 "ignoring request.\n");
5814 "vrpn_Connection_IP::server_check_for_incoming_connections:\n" 5815 " Out of memory on new endpoint\n");
5826 struct sockaddr_in peer;
5827 #ifdef VRPN_USE_WINSOCK_SOCKETS 5828 int peerlen =
sizeof(peer);
5831 int peerlen =
sizeof(peer);
5833 socklen_t peerlen =
sizeof(peer);
5836 unsigned short peer_port = 0;
5837 if (getpeername(newSocket, static_cast<struct sockaddr *>(
5838 static_cast<void *>(&peer)),
5840 peer_port = ntohs(peer.sin_port);
5852 fprintf(stderr,
"vrpn_Connection_IP::server_check_for_incoming_" 5854 "Couldn't open incoming log file.\n");
5922 for (endpointIndex = 0; endpointIndex <
d_numEndpoints; endpointIndex++) {
5932 timeout = *pTimeout;
5936 timeout.tv_usec = 0;
5953 unsigned short listen_port_no,
const char *local_in_logfile_name,
5954 const char *local_out_logfile_name,
const char *NIC_IPaddress,
5963 if (NIC_IPaddress != NULL) {
5964 char *IP =
new char[strlen(NIC_IPaddress) + 1];
5968 "vrpn_Connection_IP::vrpn_Connection_IP(): Out of memory\n");
5971 strcpy(IP, NIC_IPaddress);
5993 printf(
"vrpn: Listening for requests on port %d\n", listen_port_no);
5999 fprintf(stderr,
"Couldn't listen on TCP listening socket.\n");
6010 const char *station_name,
int port,
const char *local_in_logfile_name,
6011 const char *local_out_logfile_name,
const char *remote_in_logfile_name,
6012 const char *remote_out_logfile_name,
const char *NIC_IPaddress,
6015 remote_in_logfile_name, remote_out_logfile_name, epa)
6027 if (NIC_IPaddress != NULL) {
6028 char *IP =
new char[strlen(NIC_IPaddress) + 1];
6032 "vrpn_Connection_IP::vrpn_Connection_IP(): Out of memory\n");
6035 strcpy(IP, NIC_IPaddress);
6040 isrsh = (strstr(station_name,
"x-vrsh:") ? VRPN_TRUE : VRPN_FALSE);
6041 istcp = (strstr(station_name,
"tcp:") ? VRPN_TRUE : VRPN_FALSE);
6055 if (!isrsh && !istcp) {
6061 "vrpn_Connection_IP: Can't get remote machine name!\n");
6083 "vrpn_Connection_IP: Can't Set up socket to lob UDP packets!\n");
6091 printf(
"vrpn_Connection_IP: Getting the TCP port to listen on\n");
6096 char local_host[64];
6102 local_host) == -1) {
6103 fprintf(stderr,
"vrpn_Connection_IP: Can't create listen socket\n");
6116 fprintf(stderr,
"vrpn_Connection_IP: Can't lob UDP request\n");
6141 fprintf(stderr,
"vrpn_Connection_IP: Can't poll for accept\n");
6152 printf(
"vrpn: Connection established on initial try\n");
6157 fprintf(stderr,
"vrpn_Connection_IP: " 6158 "Can't set up new connection!\n");
6172 fprintf(stderr,
"vrpn_Connection_IP: Can't get remote machine name " 6173 "for tcp: connection!\n");
6186 printf(
"vrpn_Connection_IP: Getting the TCP port to connect with.\n");
6196 "vrpn_Connection_IP: Can't create TCP connection.\n");
6205 fprintf(stderr,
"vrpn_Connection_IP: " 6206 "Can't set up new connection!\n");
6220 char *server_program;
6227 token = server_args;
6229 while ((token = strchr(token,
',')) != NULL) {
6233 endpoint->
d_tcpSocket = vrpn_start_server(machinename, server_program,
6234 server_args, NIC_IPaddress);
6235 if (machinename)
delete[](
char *)machinename;
6236 if (server_program)
delete[](
char *)server_program;
6237 if (server_args)
delete[](
char *)server_args;
6240 fprintf(stderr,
"vrpn_Connection_IP: " 6254 fprintf(stderr,
"vrpn_Connection_IP: " 6255 "Can't set up new connection!\n");
6300 #ifdef VRPN_USE_WINSOCK_SOCKETS 6302 if (WSACleanup() == SOCKET_ERROR) {
6303 fprintf(stderr,
"~vrpn_Connection_IP(): " 6304 "WSACleanup() failed with error code %d\n",
6308 #endif // VRPN_USE_WINSOCK_SOCKETS 6337 if (fullname == NULL) {
6341 size_t len = 1 + strcspn(fullname,
"@");
6342 char *tbuf =
new char[len];
6344 fprintf(stderr,
"vrpn_copy_service_name: Out of memory!\n");
6346 strncpy(tbuf, fullname, len - 1);
6356 int offset = static_cast<int>(strcspn(fullname,
"@"));
6357 size_t len = strlen(fullname) - offset;
6360 len = strlen(fullname) + 1;
6362 char *tbuf =
new char[len];
6364 fprintf(stderr,
"vrpn_copy_service_name: Out of memory!\n");
6366 strncpy(tbuf, fullname + offset + 1, len - 1);
6379 if (!fp)
return NULL;
6381 if (!strncmp(fp,
"file://", 7)) {
6384 else if (!strncmp(fp,
"file:", 5)) {
6388 len = 1 + strlen(fp);
6389 filename =
new char[len];
6391 fprintf(stderr,
"vrpn_copy_file_name: Out of memory!\n");
6393 strncpy(filename, fp, len - 1);
6394 filename[len - 1] = 0;
6402 static int header_len(
const char *hostspecifier)
6406 if (!strncmp(hostspecifier,
"x-vrpn://", 9) ||
6407 !strncmp(hostspecifier,
"x-vrsh://", 9)) {
6410 else if (!strncmp(hostspecifier,
"x-vrpn:", 7) ||
6411 !strncmp(hostspecifier,
"x-vrsh:", 7)) {
6414 else if (!strncmp(hostspecifier,
"tcp://", 6)) {
6417 else if (!strncmp(hostspecifier,
"tcp:", 4)) {
6420 else if (!strncmp(hostspecifier,
"mpi://", 6)) {
6423 else if (!strncmp(hostspecifier,
"mpi:", 4)) {
6436 size_t nearoffset = 0;
6445 nearoffset = header_len(hostspecifier);
6450 faroffset = strcspn(hostspecifier + nearoffset,
":/");
6451 len = 1 + faroffset;
6453 tbuf =
new char[len];
6455 fprintf(stderr,
"vrpn_copy_machine_name: Out of memory!\n");
6458 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6473 pn += header_len(hostspecifier);
6475 pn = strrchr(pn,
':');
6486 size_t nearoffset = 0;
6491 nearoffset += header_len(hostspecifier);
6493 nearoffset += strcspn(hostspecifier + nearoffset,
"/");
6495 faroffset = strcspn(hostspecifier + nearoffset,
",");
6496 len = 1 + (faroffset ? faroffset : strlen(hostspecifier) - nearoffset);
6497 tbuf =
new char[len];
6500 fprintf(stderr,
"vrpn_copy_rsh_program: Out of memory!\n");
6502 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6511 size_t nearoffset = 0;
6516 nearoffset += header_len(hostspecifier);
6518 nearoffset += strcspn(hostspecifier + nearoffset,
"/");
6519 nearoffset += strcspn(hostspecifier + nearoffset,
",");
6520 faroffset = strlen(hostspecifier);
6521 len = 1 + faroffset - nearoffset;
6522 tbuf =
new char[len];
6525 fprintf(stderr,
"vrpn_copy_rsh_arguments: Out of memory!\n");
6527 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6543 size_t inputLength = strlen(specifier);
6544 size_t atSymbolIndex = strcspn(specifier,
"@");
6546 char *location = NULL;
6548 if (atSymbolIndex == inputLength) {
6550 location =
new char[inputLength + 1];
6551 strcpy(location, specifier);
6559 size_t len = strlen(location) + strlen(newServiceName);
6560 char *newSpecifier =
new char[len + 2];
6562 strcpy(newSpecifier, newServiceName);
6563 strcat(newSpecifier,
"@");
6564 strcat(newSpecifier, location);
6566 return newSpecifier;
virtual int unregister_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
const int vrpn_ANY_TYPE
vrpn_ANY_TYPE can be used to register callbacks for any USER type of message from a given sender....
vrpn_Connection * getByName(const char *name)
Searches through d_kcList but NOT d_anonList (Connections constructed with no name)
vrpn_int32 d_numEndpoints
int finish_new_connection_setup(void)
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...
virtual int dispatch(vrpn_int32 type, vrpn_int32 sender, timeval time, vrpn_uint32 payload_len, char *bufptr)
int vrpn_udp_request_lob_packet(SOCKET udp_sock, const char *machine, const int remote_port, const int local_port, const char *NIC_IP=NULL)
This section deals with implementing a method of connection termed a UDP request.
vrpn_LOGLIST * d_firstEntry
const char * vrpn_got_first_connection
These are the strings that define the system-generated message types that tell when connections are r...
vrpn_int32 udp_outbuf_size(void) const
class VRPN_API vrpn_File_Connection
void * userdata
passed along
int pack_type_description(vrpn_int32 which)
Packs a type description.
int close(void)
Closes and saves the log file.
vrpn_uint32 get_Jane_value(void)
int pack_sender_description(vrpn_int32 which)
Packs a sender description over our socket.
char * d_remoteOutLogName
Name of the remote log file.
virtual int mainloop(timeval *timeout)=0
int d_tcpListenPort
Socket and port that the client listens on when lobbing datagrams at the server and waiting for it to...
#define vrpn_CONNECTION_MAX_XLATION_TABLE_SIZE
virtual void updateEndpoints(void)
This function will be called on the mainloop() iteration after *d_endpointAllocator is called,...
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.
vrpn_int32 set_tcp_outbuf_size(vrpn_int32 bytecount)
int getOneTCPMessage(int fd, char *buf, size_t buflen)
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...
vrpn_bool d_wroteMagicCookie
int checkFilters(vrpn_int32 payloadLen, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer)
virtual int send_pending_reports(void)
send pending report, clear the buffer.
const char * vrpn_dropped_connection
vrpn_Log(vrpn_TranslationTable *senders, vrpn_TranslationTable *types)
vrpn_int32 d_serverLogMode
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
int getOneUDPMessage(char *buf, size_t buflen)
Encapsulation of the data and methods for a single IP-based connection to take care of one part of ma...
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...
vrpn_TranslationTable * d_senders
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...
char * vrpn_copy_rsh_arguments(const char *hostspecifier)
static int VRPN_CALLBACK handle_type_message(void *userdata, vrpn_HANDLERPARAM p)
size_t vrpn_cookie_size(void)
Returns the size of the magic cookie buffer, plus any alignment overhead.
virtual const char * message_type_name(vrpn_int32 type)
int connect_tcp_to(const char *msg)
Description of a callback entry for a user type.
void poll_for_cookie(const timeval *timeout=NULL)
timeval lastLogTime()
Returns the time of the last message that was logged.
int pack_udp_description(int portno)
int d_remote_port_number
Port to connect to on remote machine.
virtual timeval get_time()
returns the current time in the connection (since the epoch – UTC time).
int setName(const char *name)
vrpn_float64 d_udpAlignedInbuf[vrpn_CONNECTION_UDP_BUFLEN/sizeof(vrpn_float64)+1]
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.
virtual vrpn_bool doing_okay(void) const
const vrpn_int32 vrpn_CONNECTION_UDP_DESCRIPTION
SOCKET d_udpOutboundSocket
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...
virtual void handle_connection(int whichEndpoint)
This routine is called by a server-side connection when a new connection has just been established,...
char * vrpn_set_service_name(const char *specifier, const char *newServiceName)
Utility routine to rename the service name of a given host specifier.
int saveLogSoFar(void)
Saves any messages logged so far.
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...
vrpn_Endpoint(vrpn_TypeDispatcher *dispatcher, vrpn_int32 *connectedEndpointCounter)
virtual int send_pending_reports(void)
send pending report, clear the buffer.
int check_vrpn_cookie(const char *buffer)
Checks to see if the given buffer has the magic cookie.
vrpn_Connection * d_parent
const vrpn_int32 vrpn_CONNECTION_SENDER_DESCRIPTION
timeval vrpn_TimevalDiff(const timeval &tv1, const timeval &tv2)
void drop_connection(void)
Should only be called by vrpn_Connection::drop_connection(), since there's more housecleaning to do a...
char * vrpn_copy_file_name(const char *filespecifier)
Utility routines to parse file specifiers FROM service locations.
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...
int newRemoteSender(cName sender_name, vrpn_int32 remote_id, vrpn_int32 local_id)
virtual vrpn_bool doing_okay(void) const
Returns vrpn_true if the connection is okay, vrpn_false if not.
const vrpn_int32 vrpn_CONNECTION_DISCONNECT_MESSAGE
int newLocalType(const char *name, vrpn_int32 which)
int pack_log_description(void)
Packs the log description set by setup_new_connection().
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...
Generic connection class not specific to the transport mechanism.
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.
int setup_new_connection(void)
Sends the magic cookie and other information to its peer. It is called by both the client and server ...
char * d_remote_machine_name
Machine to call.
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 newRemoteType(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.
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_Endpoint_IP *(*epa)(vrpn_Connection *, vrpn_int32 *)=allocateEndpoint)
Make a client connection. To access this from user code, call vrpn_get_connection_by_name()....
int message_type_is_registered(const char *) const
Returns message type ID, or -1 if unregistered.
vrpn_MESSAGEHANDLER handler
Routine to call.
int handle_tcp_messages(const timeval *timeout)
virtual int time_since_connection_open(struct timeval *elapsed_time)
Returns the time since the connection opened. Some subclasses may redefine time.
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...
int(VRPN_CALLBACK * vrpn_MESSAGEHANDLER)(void *userdata, vrpn_HANDLERPARAM p)
Type of a message handler for vrpn_Connection messages.
const char * vrpn_dropped_last_connection
int mainloop(timeval *timeout)
vrpn_LOGFILTER filter
routine to call
const vrpn_int32 vrpn_CONNECTION_LOG_DESCRIPTION
virtual int send_pending_reports(void)=0
send pending report, clear the buffer. This function was protected, now is public,...
Constructor for a Loopback connection that will basically just pass messages between objects that are...
vrpn_int32 d_udpSequenceNumber
int check_vrpn_file_cookie(const char *buffer)
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...
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.
const long vrpn_LOG_OUTGOING
void addConnection(vrpn_Connection *, const char *name)
NB implementation is not particularly efficient; we expect to have O(10) connections,...
const vrpn_int32 vrpn_CONNECTION_TYPE_DESCRIPTION
SOCKET listen_tcp_sock
TCP Connection requests come here.
virtual ~vrpn_Connection_IP(void)
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...
void deleteConnection(vrpn_Connection *)
char * vrpn_copy_service_location(const char *fullname)
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>....
vrpn_int32 d_tcpSequenceNumber
static int VRPN_CALLBACK handle_UDP_message(void *userdata, vrpn_HANDLERPARAM p)
Routines that handle system messages.
char cName[100]
Length of names within VRPN.
void setConnection(vrpn_Connection *conn)
vrpnLogFilterEntry * next
This structure is what is passed to a vrpn_Connection message callback.
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...
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...
void setAutoDeleteStatus(bool setvalue)
Specify whether this connection should be deleted automatically when it is no longer need (reference ...
~vrpn_ConnectionManager(void)
virtual void init(void)
Base initialization for all constructors.
Singleton class that keeps track of all known VRPN connections and makes sure they're deleted on shut...
class VRPN_API vrpn_TranslationTable
int connectionStatus
Status of the connection.
virtual ~vrpn_Endpoint_IP(void)
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...
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 ...
virtual vrpn_bool connected(void) const
Returns vrpn_true if the connection has been established, vrpn_false if not (For a networkless connec...
static vrpn_ConnectionManager & instance(void)
The only way to get access to an instance of this class. Guarantees that there is only one,...
void * userdata
Passed along.
vrpn_int32 sender
Only if from sender.
int vrpn_noint_block_write(int outfile, const char buffer[], size_t length)
timeval start_time
Timekeeping - TCH 30 June 98.
vrpn_bool outbound_udp_open(void) const
True if the UDP outbound is open, False if not.
char * d_remoteInLogName
Name of the remote log file.
vrpn_MESSAGEHANDLER vrpn_LOGFILTER
Type of handler for filters on logfiles is the same as connection handler.
bool vrpn_TimevalGreater(const timeval &tv1, const timeval &tv2)
const char * vrpn_got_connection
long d_remoteLogMode
Mode to put the remote logging in.
virtual ~vrpn_Connection_Loopback(void)
vrpnLogFilterEntry * d_filters
Encapsulation of the data and methods for a single generic connection to take care of one part of man...
vrpn_int32 * d_connectionCounter
int compact_endpoints(void)
Makes sure the endpoint array is set up cleanly for the next pass through.
int vrpn_get_port_number(const char *hostspecifier)
void setNICaddress(const char *)
static int VRPN_CALLBACK handle_log_message(void *userdata, vrpn_HANDLERPARAM p)
Routines that handle system messages.
int vrpn_noint_block_read_timeout(SOCKET infile, char buffer[], size_t length, struct timeval *timeout)
This routine will read in a block from the file descriptor.
void setLogNames(const char *inName, const char *outName)
int d_serverLogCount
Server logging w. multiconnection - TCH July 00 Use one "hidden" endpoint for outgoing logs (?...
char * vrpn_copy_machine_name(const char *hostspecifier)
int local_type_id(vrpn_int32 remote_type) const
Returns the local mapping for the remote type (-1 if none).
virtual void drop_connection(void)=0
Should only be called by vrpn_Connection::drop_connection(), since there's more housecleaning to do a...
const long vrpn_LOG_INCOMING
int doSystemCallbacksFor(vrpn_HANDLERPARAM, void *)
virtual void server_check_for_incoming_connections(const struct timeval *timeout=NULL)
char * vrpn_copy_service_name(const char *fullname)
const int vrpn_CONNECTION_MAX_TYPES
vrpn_int32 tcp_outbuf_size(void) const
SOCKET listen_udp_sock
UDP Connect requests come here.
vrpn_Endpoint_IP(vrpn_TypeDispatcher *dispatcher, vrpn_int32 *connectedEndpointCounter)
vrpn_TranslationTable * d_senders
vrpn_bool d_updateEndpoint
virtual const char * sender_name(vrpn_int32 sender)
Returns the name of the specified sender/type, or NULL if the parameter is invalid....
long & logMode(void)
Returns a reference so we can |= it.
int vrpn_noint_block_read(int infile, char buffer[], size_t length)
char * vrpn_copy_rsh_program(const char *hostspecifier)
int handle_udp_messages(const timeval *timeout)
const int vrpn_CONNECTION_MAX_SENDERS
Types now have their storage dynamically allocated, so we can afford to have large tables....
virtual void drop_connection(int whichEndpoint)
int addFilter(vrpn_LOGFILTER filter, void *userdata)
vrpn_TranslationTable * d_types
vrpn_Connection(const char *local_in_logfile_name, const char *local_out_logfile_name, vrpn_Endpoint_IP *(*epa)(vrpn_Connection *, vrpn_int32 *)=allocateEndpoint)
Constructor for server connection. This cannot be called directly any more because vrpn_Connection is...
virtual void init(void)
Called by all constructors.
#define vrpn_gettimeofday
vrpn_Endpoint_IP * d_endpoints[vrpn_MAX_ENDPOINTS]
Sockets used to talk to remote Connection(s) and other information needed on a per-connection basis.
const char * vrpn_CONTROL
vrpn_CONTROL is the sender used for notification messages sent to the user from the local VRPN implem...
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).
vrpn_int32 d_numConnectedEndpoints
We need to track the number of connected endpoints separately to properly send out got-first-connecti...
char * getName()
Allocates a new string and copies the log file name to it. IMPORTANT: code calling this function is r...
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.
static int VRPN_CALLBACK handle_sender_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....
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...
const char * vrpn_FILE_MAGIC
class VRPN_API vrpn_TypeDispatcher
virtual int save_log_so_far()
Save any messages on any endpoints which have been logged so far.
int open(void)
Opens the log file.
int delete_endpoint(int whichEndpoint)
Deletes the endpoint and NULLs the entry in the list of open endpoints.
virtual ~vrpn_Endpoint(void)
const int vrpn_CONNECTION_TCP_BUFLEN
vrpnMsgCallbackEntry * next
Next handler.
virtual ~vrpn_Connection(void)
int logOutgoingMessage(vrpn_int32 payloadLen, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer)
virtual int pack_type_description(vrpn_int32 which)
Send the type description to ALL endpoints.
timeval d_last_connect_attempt
When the last UDP lob occurred.
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).
const int vrpn_CONNECTION_UDP_BUFLEN
SOCKET d_udpInboundSocket
Inbound unreliable messages come here. Need one for each due to different clock synchronization for e...
void clearBuffers(void)
Empties out the TCP and UDP send buffers. Needed by vrpn_FileConnection to get at {udp,...
vrpn_bool d_tcp_only
For connections made through firewalls or NAT with the tcp: URL, we do not want to allow the endpoint...
const int vrpn_MAX_ENDPOINTS
Number of endpoints that a server connection can have. Arbitrary limit.
static int VRPN_CALLBACK handle_disconnect_message(void *userdata, vrpn_HANDLERPARAM p)
vrpn_Connection_Loopback()
Make a client connection. To access this from user code, call vrpn_create_server_connection() with a ...
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...
vrpn_TypeDispatcher * d_dispatcher
Derived classes need access to d_dispatcher in their allocateEndpoint() routine. Several compilers wo...
void addReference()
Counting references to this connection.
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...
timeval vrpn_TimevalSum(const timeval &tv1, const timeval &tv2)
vrpn_TypeDispatcher * d_dispatcher
virtual vrpn_int32 register_message_type(const char *name)
SOCKET d_tcpListenSocket
This section deals with when a client connection is trying to establish (or re-establish) a connectio...
int write_vrpn_cookie(char *buffer, size_t length, long remote_log_mode)
Writes the magic cookie into buffer with given length.
int local_sender_id(vrpn_int32 remote_sender) const
Returns the local mapping for the remote sender (-1 if none).
Placed here so vrpn_FileConnection can use it too.
vrpn_TranslationTable * d_types
virtual int do_callbacks_for(vrpn_int32 type, vrpn_int32 sender, struct timeval time, vrpn_uint32 len, const char *buffer)
virtual int pack_sender_description(vrpn_int32 which)
Send the sender description to ALL endpoints.
vrpn_float64 d_tcpAlignedInbuf[vrpn_CONNECTION_TCP_BUFLEN/sizeof(vrpn_float64)+1]
SOCKET d_udpLobSocket
Socket to use to lob UDP requests asking for the server to call us back.
const int vrpn_ANY_SENDER
vrpn_ANY_SENDER can be used to register callbacks on a given message type from any sender.
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...