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++) {
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)) {
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)) {
1062 vrpn_int32 vrpn_TypeDispatcher::getSenderID(
const char *name)
1066 for (i = 0; i < d_numSenders; i++) {
1075 vrpn_int32 vrpn_TypeDispatcher::addType(
const char *name)
1080 fprintf(stderr,
"vrpn_TypeDispatcher::addType: " 1086 if (!
d_types[d_numTypes].name) {
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",
1121 fprintf(stderr,
"vrpn_TypeDispatcher::addSender: " 1122 "Can't allocate memory for new record\n");
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)
1401 d_systemMessages[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;
1455 deleteConnection(c, &d_kcList);
1456 deleteConnection(c, &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++) {
2489 #if defined(sparc) || defined(FreeBSD) || defined(_AIX) || defined(__ANDROID__) 2496 ret = vrpn_poll_for_accept(server_sock, &child_socket,
SERVWAIT);
2498 fprintf(stderr,
"vrpn_start_server: Accept poll failed\n");
2507 #if defined(hpux) || defined(sgi) || defined(__hpux) || defined(__CYGWIN__) || \ 2510 deadkid = wait3((
int *)&status, WNOHANG, NULL);
2512 deadkid = wait3(&status, WNOHANG, NULL);
2514 if (deadkid == pid) {
2515 fprintf(stderr,
"vrpn_start_server: server process exited\n");
2522 "vrpn_start_server: server failed to connect in time\n");
2523 fprintf(stderr,
" (took more than %d seconds)\n",
2532 return (child_socket);
2557 static_cast<char>(remote_log_mode +
'0'));
2579 bp = strrchr(buffer,
'.');
2582 fprintf(stderr,
"check_vrpn_cookie: " 2583 "bad cookie (wanted '%s', got '%s'\n",
2590 "check_vrpn_cookie(): " 2591 "VRPN Note: minor version number doesn't match: (prefer '%s', " 2592 "got '%s'). This is not normally a problem.\n",
2616 bp = strrchr(buffer,
'.');
2617 int majorComparison = strncmp(
2619 if (majorComparison > 0 ||
2622 fprintf(stderr,
"check_vrpn_file_cookie: " 2623 "bad cookie (wanted >='%s' and <='%s', " 2630 fprintf(stderr,
"check_vrpn_file_cookie(): " 2631 "Note: Version number doesn't match: (prefer '%s', got " 2632 "'%s'). This is not normally a problem.\n",
2645 vrpn_int32 *connectedEndpointCounter)
2647 , d_remoteLogMode(0)
2648 , d_remoteInLogName(NULL)
2649 , d_remoteOutLogName(NULL)
2654 , d_dispatcher(dispatcher)
2655 , d_connectionCounter(connectedEndpointCounter)
2661 vrpn_int32 *connectedEndpointCounter)
2665 , d_tcpListenPort(0)
2667 , d_remote_machine_name(NULL)
2668 , d_remote_port_number(0)
2669 , d_tcp_only(vrpn_FALSE)
2678 , d_tcpSequenceNumber(0)
2679 , d_udpSequenceNumber(0)
2680 , d_tcpInbuf((char *)d_tcpAlignedInbuf)
2681 , d_udpInbuf((char *)d_udpAlignedInbuf)
2682 , d_NICaddress(NULL)
2767 return d_types->mapToLocalID(remote_type);
2772 return d_senders->mapToLocalID(remote_sender);
2794 fprintf(stderr,
"vrpn_Endpoint::init: Out of memory!\n");
2801 fprintf(stderr,
"vrpn_Endpoint::init: Out of memory!\n");
2808 fprintf(stderr,
"vrpn_Endpoint::init: Out of memory!\n");
2829 fd_set readfds, exceptfds;
2830 int tcp_messages_read;
2831 int udp_messages_read;
2833 bool time_to_try_again =
false;
2847 FD_ZERO(&exceptfds);
2865 fprintf(stderr,
"vrpn_Endpoint::mainloop: select failed.\n");
2867 fprintf(stderr,
" Errno (%d): %s.\n", errno, strerror(errno));
2877 fprintf(stderr,
"vrpn_Endpoint::mainloop: Exception on socket\n");
2886 if (udp_messages_read == -1) {
2887 fprintf(stderr,
"vrpn_Endpoint::mainloop: " 2888 "UDP handling failed, dropping connection\n");
2893 if (udp_messages_read != 0)
2894 printf(
"udp message read = %d\n", udp_messages_read);
2901 if (tcp_messages_read == -1) {
2902 fprintf(stderr,
"vrpn: TCP handling failed, dropping " 2903 "connection (this is normal when a connection " 2910 if (tcp_messages_read) {
2911 printf(
"tcp_message_read %d bytes\n", tcp_messages_read);
2929 printf(
"TRYING_TO_CONNECT\n");
2936 time_to_try_again =
true;
2942 if (time_to_try_again) {
2948 fprintf(stderr,
"vrpn_Endpoint::mainloop: " 2949 "Can't set up new connection!\n");
2961 fprintf(stderr,
"vrpn_Endpoint: mainloop: Can't poll for accept\n");
2968 printf(
"vrpn: Connection established\n");
2973 fprintf(stderr,
"vrpn_Endpoint: mainloop: " 2974 "Can't set up new connection!\n");
2986 if (time_to_try_again) {
3003 "vrpn_Endpoint: mainloop: Can't lob UDP request\n");
3019 fprintf(stderr,
"vrpn_Endpoint::mainloop(): " 3020 "Unknown status (%d)\n",
3044 return d_senders->addLocalID(name, which);
3053 return d_types->addLocalID(name, which);
3058 vrpn_int32 local_id)
3060 return d_types->addRemoteEntry(type_name, remote_id, local_id);
3065 vrpn_int32 local_id)
3067 return d_senders->addRemoteEntry(sender_name, remote_id, local_id);
3086 vrpn_int32 type, vrpn_int32 sender,
3088 vrpn_uint32 class_of_service)
3101 fprintf(stderr,
"vrpn_Endpoint::pack_message: " 3102 "Couldn't log outgoing message.!\n");
3114 fprintf(stderr,
"vrpn_Endpoint::pack_message: " 3115 "Not connected, so throwing out message.\n");
3150 return (!ret) ? -1 : 0;
3155 vrpn_int32 ret, sent = 0;
3162 "vrpn_Endpoint::send_pending_reports(): No TCP connection\n");
3171 timeout.tv_usec = 0;
3178 NULL, &f, &timeout);
3180 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports(): " 3181 "select() failed.\n");
3182 #ifdef VRPN_USE_WINSOCK_SOCKETS 3185 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
3186 FORMAT_MESSAGE_MAX_WIDTH_MASK,
3187 NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
3188 (LPSTR)Message, 1024, NULL);
3189 fprintf(stderr,
"Windows Sockets Error (%d): %s.\n", WSAGetLastError(),
3192 fprintf(stderr,
"Errno (%d): %s.\n", errno, strerror(errno));
3208 printf(
"TCP Sent %d bytes\n", ret);
3211 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports: " 3212 "TCP send failed.\n");
3228 printf(
"UDP Sent %d bytes\n", ret);
3231 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports: " 3232 " UDP send failed.");
3252 vrpn_uint32 portparam = portno;
3253 char myIPchar[1000];
3257 fprintf(stderr,
"Getting IP address of NIC %s.\n",
d_NICaddress);
3266 perror(
"vrpn_Endpoint::pack_udp_description: can't get host name");
3276 fprintf(stderr,
"vrpn_Endpoint::pack_udp_description: " 3277 "Packing UDP %s:%d\n",
3282 return pack_message(static_cast<vrpn_uint32>(strlen(myIPchar)) + 1, now,
3293 const char *inName =
"";
3294 const char *outName =
"";
3304 2 *
sizeof(vrpn_int32) + strlen(inName) + 1 + strlen(outName) + 1;
3305 char *buf =
new char[bufsize];
3308 "vrpn_Endpoint::pack_log_description(): Out of memory\n");
3327 vrpn_int32 bufleft =
static_cast<vrpn_int32
>(bufsize);
3328 vrpn_buffer(bp, &bufleft, (vrpn_int32)strlen(inName));
3329 vrpn_buffer(bp, &bufleft, (vrpn_int32)strlen(outName));
3330 vrpn_buffer(bp, &bufleft, inName, static_cast<vrpn_int32>(strlen(inName)));
3333 static_cast<vrpn_int32>(strlen(outName)));
3335 int ret =
pack_message(static_cast<vrpn_uint32>(bufsize - bufleft), now,
3348 timeval localTimeout;
3349 fd_set readfds, exceptfds;
3350 unsigned num_messages_read = 0;
3355 printf(
"vrpn_Endpoint::handle_tcp_messages() called\n");
3359 localTimeout.tv_sec = timeout->tv_sec;
3360 localTimeout.tv_usec = timeout->tv_usec;
3363 localTimeout.tv_sec = 0;
3364 localTimeout.tv_usec = 0;
3377 FD_ZERO(&exceptfds);
3381 NULL, &exceptfds, &localTimeout);
3382 if (sel_ret == -1) {
3383 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: " 3390 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: " 3391 "Exception on socket\n");
3404 num_messages_read++;
3416 return num_messages_read;
3433 timeval localTimeout;
3434 fd_set readfds, exceptfds;
3435 unsigned num_messages_read = 0;
3440 printf(
"vrpn_Endpoint::handle_udp_messages() called\n");
3444 localTimeout.tv_sec = timeout->tv_sec;
3445 localTimeout.tv_usec = timeout->tv_usec;
3448 localTimeout.tv_sec = 0;
3449 localTimeout.tv_usec = 0;
3461 FD_ZERO(&exceptfds);
3465 &readfds, NULL, &exceptfds, &localTimeout);
3466 if (sel_ret == -1) {
3467 perror(
"vrpn_Endpoint::handle_udp_messages: select failed()");
3473 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_udp_messages: " 3474 "Exception on socket\n");
3486 if (inbuf_len == -1) {
3487 fprintf(stderr,
"vrpn_Endpoint::handle_udp_message: " 3488 "recv() failed.\n");
3497 inbuf_len -= retval;
3498 inbuf_ptr += retval;
3502 num_messages_read++;
3516 return num_messages_read;
3531 if (sscanf(msg,
"%s %d", machine, &port) != 2) {
3540 struct sockaddr_in client;
3541 struct hostent *host;
3546 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: " 3547 "can't open socket\n");
3550 client.sin_family = AF_INET;
3558 if ((client.sin_addr.s_addr = inet_addr(addr)) == INADDR_NONE) {
3559 host = gethostbyname(addr);
3565 u_long foo_mark = 0;
3566 for (i = 0; i < 4; i++) {
3567 u_long one_char = host->h_addr_list[0][i];
3568 foo_mark = (foo_mark << 8) | one_char;
3570 client.sin_addr.s_addr = foo_mark;
3573 memcpy(&(client.sin_addr.s_addr), host->h_addr, host->h_length);
3578 #if !defined(hpux) && !defined(__hpux) && !defined(_WIN32) && !defined(sparc) 3579 herror(
"gethostbyname error:");
3581 perror(
"gethostbyname error:");
3583 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: " 3584 "error finding host by name (%s)\n",
3590 #ifndef VRPN_USE_WINSOCK_SOCKETS 3591 client.sin_port = htons(port);
3593 client.sin_port = htons((u_short)port);
3596 if (connect(
d_tcpSocket, (
struct sockaddr *)&client,
sizeof(client)) < 0) {
3597 #ifdef VRPN_USE_WINSOCK_SOCKETS 3599 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: Could not connect " 3600 "to machine %d.%d.%d.%d port %d\n",
3601 (
int)(client.sin_addr.S_un.S_un_b.s_b1),
3602 (
int)(client.sin_addr.S_un.S_un_b.s_b2),
3603 (
int)(client.sin_addr.S_un.S_un_b.s_b3),
3604 (
int)(client.sin_addr.S_un.S_un_b.s_b4),
3605 (
int)(ntohs(client.sin_port)));
3606 int error = WSAGetLastError();
3607 fprintf(stderr,
"Winsock error: %d\n", error);
3610 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: Could not connect to " 3611 "machine %d.%d.%d.%d port %d\n",
3612 (
int)((client.sin_addr.s_addr >> 24) & 0xff),
3613 (
int)((client.sin_addr.s_addr >> 16) & 0xff),
3614 (
int)((client.sin_addr.s_addr >> 8) & 0xff),
3615 (
int)((client.sin_addr.s_addr >> 0) & 0xff),
3616 (
int)(ntohs(client.sin_port)));
3624 #if !defined(_WIN32_WCE) && !defined(__ANDROID__) 3626 struct protoent *p_entry;
3629 if ((p_entry = getprotobyname(
"TCP")) == NULL) {
3632 "vrpn_Endpoint::connect_tcp_to: getprotobyname() failed.\n");
3638 if (setsockopt(
d_tcpSocket, p_entry->p_proto, TCP_NODELAY,
3639 SOCK_CAST & nonzero,
sizeof(nonzero)) == -1) {
3640 perror(
"vrpn_Endpoint::connect_tcp_to: setsockopt() failed");
3657 fprintf(stderr,
"vrpn_Endpoint::connect_udp_to: " 3658 "Couldn't open outbound UDP link.\n");
3670 if (bytecount < 0) {
3674 new_outbuf =
new char[bytecount];
3732 fprintf(stderr,
"vrpn_Endpoint::drop_connection: Can't log\n");
3747 (*d_connectionCounter)--;
3774 fprintf(stderr,
"Setting endpoint NIC address to %s.\n", address);
3783 fprintf(stderr,
"vrpn_Endpoint::setNICaddress: Out of memory.\n");
3798 perror(
"vrpn_Endpoint::setup_new_connection: " 3799 "Internal error - array too small. The code's broken.");
3809 fprintf(stderr,
"vrpn_Endpoint::setup_new_connection: " 3810 "Can't write cookie.\n");
3826 timeout = *pTimeout;
3830 timeout.tv_usec = 0;
3833 fd_set readfds, exceptfds;
3842 FD_ZERO(&exceptfds);
3852 &exceptfds, &timeout) == -1) {
3853 fprintf(stderr,
"vrpn_Endpoint::poll_for_cookie(): select failed.\n");
3861 "vrpn_Endpoint::poll_for_cookie(): Exception on socket\n");
3870 "vrpn_Endpoint::poll_for_cookie: cookie handling failed\n" 3871 " while connecting to \"%s\"\n",
3877 printf(
"vrpn_Endpoint::poll_for_cookie() got cookie\n");
3887 char *recvbuf =
new char[sendlen];
3888 if (recvbuf == NULL) {
3889 fprintf(stderr,
"vrpn_Endpoint_IP::finish_new_connection_setup(): Out " 3890 "of memory when allocating receiver buffer\n");
3897 if (ret != sendlen) {
3898 perror(
"vrpn_Endpoint::finish_new_connection_setup: Can't read cookie");
3921 if ((received_logmode < 0) ||
3923 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: " 3924 "Got invalid log mode %d\n",
3925 static_cast<int>(received_logmode));
3942 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: " 3943 "Can't pack remote logging instructions.\n");
3957 unsigned short udp_portnum =
static_cast<unsigned short>(INADDR_ANY);
3960 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: " 3961 "can't open UDP socket\n");
3969 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: " 3970 "Can't pack UDP msg\n");
3980 "CONNECTED - vrpn_Endpoint::finish_new_connection_setup.\n");
3997 "vrpn_Endpoint::finish_new_connection_setup: Can't send UDP msg\n");
4023 (*d_connectionCounter)++;
4032 vrpn_int32 header[5];
4033 struct timeval time;
4034 vrpn_int32 sender, type;
4035 size_t len, payload_len, ceil_len;
4040 "vrpn_Endpoint::handle_tcp_messages(): something to read\n");
4046 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: " 4047 "Can't read header (this is normal when a connection " 4051 len = ntohl(header[0]);
4052 time.tv_sec = ntohl(header[1]);
4053 time.tv_usec = ntohl(header[2]);
4054 sender = ntohl(header[3]);
4055 type = ntohl(header[4]);
4057 fprintf(stderr,
" header: Len %d, Sender %d, Type %d\n", (
int)len,
4058 (
int)sender, (
int)type);
4062 vrpn_int32 header_len =
sizeof(header);
4064 header_len += vrpn_ALIGN - header_len %
vrpn_ALIGN;
4066 if (header_len > static_cast<vrpn_int32>(
sizeof(header))) {
4070 header_len -
sizeof(header)) !=
4071 (int)(header_len -
sizeof(header))) {
4072 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: " 4073 "Can't read header + alignment\n");
4081 payload_len = len - header_len;
4082 ceil_len = payload_len;
4083 if (ceil_len % vrpn_ALIGN) {
4084 ceil_len += vrpn_ALIGN - ceil_len %
vrpn_ALIGN;
4089 if (buflen < ceil_len) {
4091 "vrpn: vrpn_Endpoint::handle_tcp_messages: Message too long\n");
4097 perror(
"vrpn: vrpn_Endpoint::handle_tcp_messages: Can't read body");
4102 fprintf(stderr,
"Couldn't log incoming message.!\n");
4106 retval =
dispatch(type, sender, time, static_cast<vrpn_uint32>(payload_len),
4117 vrpn_int32 header[5];
4118 struct timeval time;
4119 vrpn_int32 sender, type;
4120 vrpn_uint32 len, payload_len, ceil_len;
4125 vrpn_uint32 header_len =
sizeof(header);
4127 header_len += vrpn_ALIGN - header_len %
vrpn_ALIGN;
4130 if (header_len > (vrpn_uint32)inbuf_len) {
4131 fprintf(stderr,
"vrpn_Endpoint::getOneUDPMessage: Can't read header");
4134 memcpy(header, inbuf_ptr,
sizeof(header));
4135 inbuf_ptr += header_len;
4136 len = ntohl(header[0]);
4137 time.tv_sec = ntohl(header[1]);
4138 time.tv_usec = ntohl(header[2]);
4139 sender = ntohl(header[3]);
4140 type = ntohl(header[4]);
4143 fprintf(stderr,
"Message type %ld (local type %ld), sender %ld received\n",
4145 fprintf(stderr,
"Message length is %d (buffer length %d).\n", len,
4152 payload_len = len - header_len;
4153 ceil_len = payload_len;
4154 if (ceil_len % vrpn_ALIGN) {
4155 ceil_len += vrpn_ALIGN - ceil_len %
vrpn_ALIGN;
4159 if (header_len + ceil_len > (vrpn_uint32)inbuf_len) {
4160 fprintf(stderr,
"vrpn_Endpoint::getOneUDPMessage: Can't read payload");
4166 fprintf(stderr,
"Couldn't log incoming message.!\n");
4170 retval =
dispatch(type, sender, time, payload_len, inbuf_ptr);
4175 return ceil_len + header_len;
4179 vrpn_uint32 payload_len,
char *bufptr)
4191 payload_len, bufptr)) {
4198 if (
d_dispatcher->doSystemCallbacksFor(type, sender, time, payload_len,
4200 fprintf(stderr,
"vrpn_Endpoint::dispatch: " 4201 "Nonzero system return\n");
4210 vrpn_int32 &numOut, vrpn_uint32 len,
4211 timeval time, vrpn_int32 type,
4212 vrpn_int32 sender,
const char *buffer,
4213 vrpn_uint32 sequenceNumber)
4218 buffer, sequenceNumber);
4228 sender, buffer, sequenceNumber);
4246 vrpn_uint32 outbuf_size,
4247 vrpn_uint32 initial_out,
4249 struct timeval time,
4255 vrpn_uint32 ceil_len, header_len, total_len;
4256 vrpn_uint32 curr_out = initial_out;
4267 header_len = 5 *
sizeof(vrpn_int32);
4268 if (header_len % vrpn_ALIGN) {
4269 header_len += vrpn_ALIGN - header_len %
vrpn_ALIGN;
4271 total_len = header_len + ceil_len;
4272 if ((curr_out + total_len) > (vrpn_uint32)outbuf_size) {
4286 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(header_len + len);
4287 curr_out +=
sizeof(vrpn_uint32);
4291 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(time.tv_sec);
4292 curr_out +=
sizeof(vrpn_uint32);
4293 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(time.tv_usec);
4294 curr_out +=
sizeof(vrpn_uint32);
4297 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(sender);
4298 curr_out +=
sizeof(vrpn_uint32);
4299 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(type);
4300 curr_out +=
sizeof(vrpn_uint32);
4305 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(seqNo);
4306 curr_out +=
sizeof(vrpn_uint32);
4309 curr_out = initial_out + header_len;
4314 if (buffer != NULL) {
4315 memcpy(&outbuf[curr_out], buffer, len);
4317 curr_out += ceil_len;
4319 printf(
"Marshalled: len %d, ceil_len %d: '", len, ceil_len);
4322 return curr_out - initial_out;
4331 vrpn_int32 local_id;
4334 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_type_message: " 4335 "Type name too long\n");
4340 strncpy(type_name, p.
buffer +
sizeof(vrpn_int32),
4345 i = ntohl(*((vrpn_int32 *)p.
buffer));
4346 type_name[i] =
'\0';
4349 printf(
"Registering other-side type: '%s'\n", type_name);
4352 local_id = endpoint->
d_dispatcher->getTypeID(type_name);
4354 if (local_id == -1) {
4360 printf(
"vrpn_Endpoint::handle_type_message: NULL d_parent " 4361 "when trying to auto-register remote message type %s.\n",
4367 fprintf(stderr,
"vrpn: Failed to add remote type %s\n", type_name);
4376 if (inName != NULL) {
4379 if (outName != NULL) {
4403 vrpn_int32 local_id;
4406 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_sender_message():Sender " 4412 strncpy(sender_name, p.
buffer +
sizeof(vrpn_int32),
4417 i = ntohl(*((vrpn_int32 *)p.
buffer));
4418 sender_name[i] =
'\0';
4421 printf(
"Registering other-side sender: '%s'\n", sender_name);
4424 local_id = endpoint->
d_dispatcher->getSenderID(sender_name);
4426 if (local_id == -1) {
4432 printf(
"vrpn_Endpoint::handle_sender_message: NULL d_parent " 4433 "when trying to auto-register remote message sender %s\n",
4439 fprintf(stderr,
"vrpn: Failed to add remote sender %s\n", sender_name);
4452 static_cast<vrpn_int32
>(strlen(
d_dispatcher->typeName(which)) + 1);
4454 char buffer[
sizeof(len) +
sizeof(
cName)];
4456 netlen = htonl(len);
4463 printf(
" vrpn_Connection: Packing type '%s', %d\n",
4466 memcpy(buffer, &netlen,
sizeof(netlen));
4467 memcpy(&buffer[
sizeof(len)],
d_dispatcher->typeName(which),
4471 return pack_message((vrpn_uint32)(len +
sizeof(len)), now,
4482 static_cast<vrpn_int32
>(strlen(
d_dispatcher->senderName(which)) + 1);
4484 char buffer[
sizeof(len) +
sizeof(
cName)];
4486 netlen = htonl(len);
4493 printf(
" vrpn_Connection: Packing sender '%s'\n",
4496 memcpy(buffer, &netlen,
sizeof(netlen));
4497 memcpy(&buffer[
sizeof(len)],
d_dispatcher->senderName(which),
4501 return pack_message((vrpn_uint32)(len +
sizeof(len)), now,
4506 static int flush_udp_socket(
SOCKET fd)
4508 timeval localTimeout;
4509 fd_set readfds, exceptfds;
4515 localTimeout.tv_sec = 0;
4516 localTimeout.tv_usec = 0;
4524 FD_ZERO(&exceptfds);
4525 FD_SET(fd, &readfds);
4526 FD_SET(fd, &exceptfds);
4528 &exceptfds, &localTimeout);
4529 if (sel_ret == -1) {
4530 fprintf(stderr,
"flush_udp_socket: select failed().");
4535 if (FD_ISSET(fd, &exceptfds)) {
4536 fprintf(stderr,
"flush_udp_socket: Exception on socket.\n");
4541 if (FD_ISSET(fd, &readfds)) {
4544 inbuf_len = recv(fd, buf, 10000, 0);
4545 if (inbuf_len == -1) {
4546 fprintf(stderr,
"flush_udp_socket: recv() failed.\n");
4561 for (i = 0; i < d_numEndpoints; i++) {
4562 if (d_endpoints[i]) {
4563 retval = d_endpoints[i]->pack_type_description(which);
4578 for (i = 0; i < d_numEndpoints; i++) {
4579 if (d_endpoints[i]) {
4580 retval = d_endpoints[i]->pack_sender_description(which);
4595 vrpn_int32 inNameLen, outNameLen;
4596 const char **bp = &p.
buffer;
4605 endpoint->
setLogNames(inNameLen == 0 ? NULL : *bp,
4606 outNameLen == 0 ? NULL : *bp + inNameLen + 1);
4607 if (inNameLen > 0) retval = endpoint->
d_inLog->
open();
4608 if (outNameLen > 0) retval = endpoint->
d_outLog->
open();
4623 fprintf(stderr,
"vrpn_Connection::handle_log_message: " 4624 "Remote connection requested logging.\n");
4643 vrpn_int32 type, vrpn_int32 sender,
4645 vrpn_uint32 class_of_service)
4650 if (connectionStatus ==
BROKEN) {
4651 printf(
"vrpn_Connection::pack_message: Can't pack because the " 4652 "connection is broken\n");
4658 printf(
"vrpn_Connection::pack_message: bad type (%d)\n", type);
4664 if ((sender < 0) || (sender >=
d_dispatcher->numSenders())) {
4665 printf(
"vrpn_Connection::pack_message: bad sender (%d)\n", sender);
4675 for (i = 0; i < d_numEndpoints; i++) {
4676 if (d_endpoints[i] &&
4677 (d_endpoints[i]->
pack_message(len, time, type, sender, buffer,
4678 class_of_service) != 0)) {
4690 if (do_callbacks_for(type, sender, time, len, buffer)) {
4737 for (i = 0; i < d_numEndpoints; i++) {
4738 d_endpoints[i]->d_inLog->addFilter(filter, userdata);
4739 d_endpoints[i]->d_outLog->addFilter(filter, userdata);
4748 int final_retval = 0;
4749 for (i = 0; i < d_numEndpoints; i++) {
4750 final_retval |= d_endpoints[i]->d_inLog->saveLogSoFar();
4751 final_retval |= d_endpoints[i]->d_outLog->saveLogSoFar();
4753 return final_retval;
4771 d_endpoints[i] = NULL;
4790 handle_disconnect_message);
4792 d_stop_processing_messages_after = 0;
4807 d_endpoints[endpointIndex] = NULL;
4820 for (i = 0; i < d_numEndpoints; i++) {
4821 if (!d_endpoints[i]) {
4822 d_endpoints[i] = d_endpoints[d_numEndpoints - 1];
4823 d_endpoints[d_numEndpoints - 1] = NULL;
4835 const char *local_out_logfile_name,
4839 , d_numConnectedEndpoints(0)
4841 , d_autoDeleteStatus(
false)
4843 , d_serverLogCount(0)
4847 , d_serverLogName(NULL)
4848 , d_endpointAllocator(epa)
4849 , d_updateEndpoint(vrpn_FALSE)
4859 handle_log_message);
4861 if (local_out_logfile_name) {
4862 d_endpoints[0] = (*d_endpointAllocator)(
this, NULL);
4863 if (!d_endpoints[0]) {
4864 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d " 4865 "Couldn't create endpoint for log file.\n",
4867 connectionStatus =
BROKEN;
4870 endpoint = d_endpoints[0];
4872 d_updateEndpoint = vrpn_TRUE;
4877 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d " 4878 "Couldn't open outgoing log file.\n",
4880 delete d_endpoints[0];
4881 d_endpoints[0] = NULL;
4882 connectionStatus =
BROKEN;
4895 if (local_in_logfile_name) {
4896 d_serverLogName =
new char[1 + strlen(local_in_logfile_name)];
4897 if (!d_serverLogName) {
4898 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d " 4901 connectionStatus =
BROKEN;
4904 strcpy(d_serverLogName, local_in_logfile_name);
4909 const char *local_in_logfile_name,
const char *local_out_logfile_name,
4910 const char *remote_in_logfile_name,
const char *remote_out_logfile_name,
4912 : connectionStatus(
BROKEN)
4915 , d_numConnectedEndpoints(0)
4917 , d_autoDeleteStatus(
false)
4919 , d_serverLogCount(0)
4921 , d_serverLogName(NULL)
4922 , d_endpointAllocator(epa)
4923 , d_updateEndpoint(vrpn_FALSE)
4932 d_endpoints[0] = (*d_endpointAllocator)(
this, &d_numConnectedEndpoints);
4933 d_endpoints[0]->setConnection(
this);
4934 d_updateEndpoint = vrpn_TRUE;
4935 if (!d_endpoints[0]) {
4936 fprintf(stderr,
"vrpn_Connection:%d Out of memory.\n", __LINE__);
4937 connectionStatus =
BROKEN;
4942 endpoint = d_endpoints[0];
4946 (((remote_in_logfile_name && strlen(remote_in_logfile_name) > 0)
4949 ((remote_out_logfile_name && strlen(remote_out_logfile_name) > 0)
4952 if (!remote_in_logfile_name) {
4958 new char[strlen(remote_in_logfile_name) + 1];
4962 if (!remote_out_logfile_name) {
4968 new char[strlen(remote_out_logfile_name) + 1];
4975 if (local_in_logfile_name && (strlen(local_in_logfile_name) != 0)) {
4980 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d " 4981 "Couldn't open incoming log file.\n",
4983 connectionStatus =
BROKEN;
4990 if (local_out_logfile_name && (strlen(local_out_logfile_name) != 0)) {
4995 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d " 4996 "Couldn't open local outgoing log file.\n",
4998 connectionStatus =
BROKEN;
5015 if (d_references > 0) {
5017 "Connection was deleted while %d references still remain.\n",
5033 if (d_references == 0 && d_autoDeleteStatus ==
true) {
5036 else if (d_references < 0) {
5038 fprintf(stderr,
"Negative reference count. This shouldn't happen.");
5048 fprintf(stderr,
"vrpn_Connection::register_sender: " 5049 "%d senders; new name \"%s\"\n",
5057 fprintf(stderr,
"Sender already defined as id %d.\n", retval);
5065 fprintf(stderr,
"Packing sender description for %s, type %d.\n", name,
5076 for (i = 0; i < d_numEndpoints; i++) {
5077 d_endpoints[i]->newLocalSender(name, retval);
5090 fprintf(stderr,
"vrpn_Connection::register_message_type: " 5091 "%d type; new name \"%s\"\n",
5099 fprintf(stderr,
"Type already defined as id %d.\n", retval);
5111 fprintf(stderr,
"Packing type description for %s, type %d.\n", name,
5119 for (i = 0; i < d_numEndpoints; i++) {
5120 d_endpoints[i]->newLocalType(name, retval);
5132 struct timeval time,
5133 vrpn_uint32 payload_len,
const char *buf)
5135 return d_dispatcher->doCallbacksFor(type, sender, time, payload_len, buf);
5144 char **local_out_logname,
5145 char **remote_in_logname,
5146 char **remote_out_logname)
5148 if (!(d_endpoints[0]))
return;
5153 if (local_in_logname != NULL)
5155 if (local_out_logname != NULL)
5158 if (remote_in_logname != NULL) {
5160 *remote_in_logname =
5165 *remote_in_logname = NULL;
5169 if (remote_out_logname != NULL) {
5171 *remote_out_logname =
5176 *remote_out_logname = NULL;
5186 vrpn_int32 *connectedEC)
5202 printf(
"Just read disconnect message from logfile\n");
5211 void *userdata, vrpn_int32 sender)
5213 return d_dispatcher->addHandler(type, handler, userdata, sender);
5218 void *userdata, vrpn_int32 sender)
5220 return d_dispatcher->removeHandler(type, handler, userdata, sender);
5237 for (endpointIndex = 0; endpointIndex < d_numEndpoints; endpointIndex++) {
5238 if (d_endpoints[endpointIndex] &&
5239 (!d_endpoints[endpointIndex]->
doing_okay())) {
5243 return (connectionStatus >
BROKEN);
5251 for (endpointIndex = 0; endpointIndex < d_numEndpoints; endpointIndex++) {
5252 if (d_endpoints[endpointIndex] &&
5288 const char *cname,
const char *local_in_logfile_name,
5289 const char *local_out_logfile_name,
const char *remote_in_logfile_name,
5290 const char *remote_out_logfile_name,
const char *NIC_IPaddress,
5291 bool force_connection)
5293 if (cname == NULL) {
5294 fprintf(stderr,
"vrpn_get_connection_by_name(): NULL name\n");
5300 const char *where_at;
5301 if ((where_at = strrchr(cname,
'@')) != NULL) {
5302 cname = where_at + 1;
5306 if (!force_connection) {
5318 int is_file = !strncmp(cname,
"file:", 5);
5322 local_out_logfile_name);
5326 cname, port, local_in_logfile_name, local_out_logfile_name,
5327 remote_in_logfile_name, remote_out_logfile_name, NIC_IPaddress);
5334 fprintf(stderr,
"Could not create new connection.");
5369 const char *local_in_logfile_name,
5370 const char *local_out_logfile_name)
5375 if (cname == NULL) {
5376 fprintf(stderr,
"vrpn_create_server_connection(): NULL name\n");
5380 if (location == NULL) {
5383 int is_loopback = !strncmp(cname,
"loopback:", 9);
5384 int is_mpi = !strncmp(cname,
"mpi:", 4);
5387 XXX_implement_MPI_server_connection;
5389 fprintf(stderr,
"vrpn_create_server_connection(): MPI support not " 5390 "compiled in. Set VRPN_USE_MPI in vrpn_Configure.h " 5391 "and recompile.\n");
5395 }
else if (is_loopback) {
5404 if (strlen(location) == 0) {
5406 local_in_logfile_name,
5407 local_out_logfile_name);
5415 if (strlen(machine) == 0) {
5419 unsigned short port =
5422 local_out_logfile_name, machine);
5431 fprintf(stderr,
"vrpn_create_server_connection(): Could not create new " 5456 if (connectionStatus !=
LISTEN) {
5460 int which_end = d_numEndpoints;
5464 fprintf(stderr,
"vrpn_Connection_IP::connect_to_client:" 5465 " Too many existing connections.\n");
5469 d_endpoints[which_end] =
5470 (*d_endpointAllocator)(
this, &d_numConnectedEndpoints);
5471 d_endpoints[which_end]->setConnection(
this);
5472 d_updateEndpoint = vrpn_TRUE;
5476 fprintf(stderr,
"vrpn_Connection_IP::connect_to_client:" 5477 " Out of memory on new endpoint\n");
5482 sprintf(msg,
"%s %d", machine, port);
5483 printf(
"vrpn_Connection_IP::connect_to_client: " 5484 "Connection request received: %s\n",
5493 handle_connection(which_end);
5507 fprintf(stderr,
"vrpn_Connection_IP::handle_connection(): " 5508 "Can't set up new connection!\n");
5525 printf(
" Received request for UDP channel to %s\n", p.
buffer);
5529 strncpy(rhostname, p.
buffer,
sizeof(rhostname));
5530 rhostname[
sizeof(
rhostname) - 1] =
'\0';
5547 printf(
" Opened UDP channel to %s:%d\n", rhostname, p.
sender);
5556 for (i = 0; i < d_numEndpoints; i++) {
5558 fprintf(stderr,
"vrpn_Connection_IP::send_pending_reports: " 5559 "Closing failed endpoint.\n");
5564 compact_endpoints();
5572 #ifdef VRPN_USE_WINSOCK_SOCKETS 5579 winStatus = WSAStartup(MAKEWORD(1, 1), &wsaData);
5581 fprintf(stderr,
"vrpn_Connection_IP::init(): " 5582 "Failed to set up sockets.\n");
5583 fprintf(stderr,
"WSAStartup failed with error code %d\n", winStatus);
5586 #endif // windows sockets 5594 #ifndef _WIN32 // XXX what about cygwin? 5596 signal(SIGPIPE, (
void (*)(
int))SIG_IGN);
5598 signal(SIGPIPE, SIG_IGN);
5604 handle_UDP_message);
5621 const struct timeval *pTimeout)
5626 int which_end = d_numEndpoints;
5631 timeout = *pTimeout;
5635 timeout.tv_usec = 0;
5643 FD_SET(listen_udp_sock, &f);
5646 if (request == -1) {
5648 "vrpn_Connection_IP::server_check_for_incoming_connections(): " 5649 "select failed.\n");
5650 connectionStatus =
BROKEN;
5655 else if (request != 0) {
5656 struct sockaddr_in from;
5657 int fromlen =
sizeof(from);
5660 if (recvfrom(listen_udp_sock, msg,
sizeof(msg) - 1, 0,
5661 (
struct sockaddr *)&from,
GSN_CAST & fromlen) == -1) {
5663 "vrpn: Error on recvfrom: Bad connection attempt\n");
5668 msg[
sizeof(msg) - 1] =
'\0';
5674 char fromname[1024];
5675 unsigned long addr_num = ntohl(from.sin_addr.s_addr);
5676 sprintf(fromname,
"%lu.%lu.%lu.%lu", (addr_num) >> 24,
5677 (addr_num >> 16) & 0xff, (addr_num >> 8) & 0xff,
5679 printf(
"vrpn: Connection request received from %s: %s\n", fromname,
5690 char *checkHost =
new char[strlen(msg) + 1];
5692 if (checkHost == NULL) {
5694 "server_check_for_incoming_connections(): Out of memory\n");
5697 if (sscanf(msg,
"%s %d", checkHost, &checkPort) != 2) {
5700 "server_check_for_incoming_connections(): Malformed request\n");
5704 if (checkPort < 1024) {
5706 "server_check_for_incoming_connections(): Bad port\n");
5713 for (checkLoop = 0; checkLoop < strlen(checkHost); checkLoop++) {
5714 char checkChar = checkHost[checkLoop];
5715 if (!isalnum(checkChar) && (checkChar !=
'.')) {
5718 "server_check_for_incoming_connections(): Bad hostname\n");
5727 fprintf(stderr,
"vrpn: Too many existing connections; " 5728 "ignoring request from %s\n",
5735 d_endpoints[which_end] =
5736 (*d_endpointAllocator)(
this, &d_numConnectedEndpoints);
5737 d_endpoints[which_end]->setConnection(
this);
5738 d_updateEndpoint = vrpn_TRUE;
5739 endpoint = d_endpoints[which_end];
5743 "vrpn_Connection_IP::server_check_for_incoming_connections:\n" 5744 " Out of memory on new endpoint\n");
5752 (d_serverLogName != NULL)) {
5759 fprintf(stderr,
"vrpn_Connection_IP::server_check_for_incoming_" 5761 "Couldn't open log file.\n");
5762 connectionStatus =
BROKEN;
5779 sscanf(msg,
"%*s %d", &port);
5784 handle_connection(which_end);
5792 flush_udp_socket(listen_udp_sock);
5800 retval = vrpn_poll_for_accept(listen_tcp_sock, &newSocket);
5803 fprintf(stderr,
"Error accepting on TCP socket.\n");
5808 printf(
"vrpn: TCP connection request received.\n");
5811 fprintf(stderr,
"vrpn: Too many existing connections; " 5812 "ignoring request.\n");
5816 d_endpoints[which_end] =
5817 (*d_endpointAllocator)(
this, &d_numConnectedEndpoints);
5818 d_endpoints[which_end]->setConnection(
this);
5819 d_updateEndpoint = vrpn_TRUE;
5820 endpoint = d_endpoints[which_end];
5824 "vrpn_Connection_IP::server_check_for_incoming_connections:\n" 5825 " Out of memory on new endpoint\n");
5836 struct sockaddr_in peer;
5837 #ifdef VRPN_USE_WINSOCK_SOCKETS 5838 int peerlen =
sizeof(peer);
5841 int peerlen =
sizeof(peer);
5843 socklen_t peerlen =
sizeof(peer);
5846 unsigned short peer_port = 0;
5847 if (getpeername(newSocket, static_cast<struct sockaddr *>(
5848 static_cast<void *>(&peer)),
5850 peer_port = ntohs(peer.sin_port);
5862 fprintf(stderr,
"vrpn_Connection_IP::server_check_for_incoming_" 5864 "Couldn't open incoming log file.\n");
5865 connectionStatus =
BROKEN;
5875 handle_connection(which_end);
5894 delete_endpoint(whichEndpoint);
5904 if (d_updateEndpoint) {
5906 d_updateEndpoint = vrpn_FALSE;
5928 if (connectionStatus ==
LISTEN) {
5929 server_check_for_incoming_connections(pTimeout);
5932 for (endpointIndex = 0; endpointIndex < d_numEndpoints; endpointIndex++) {
5933 endpoint = d_endpoints[endpointIndex];
5942 timeout = *pTimeout;
5946 timeout.tv_usec = 0;
5957 compact_endpoints();
5963 unsigned short listen_port_no,
const char *local_in_logfile_name,
5964 const char *local_out_logfile_name,
const char *NIC_IPaddress,
5973 if (NIC_IPaddress != NULL) {
5974 char *IP =
new char[strlen(NIC_IPaddress) + 1];
5978 "vrpn_Connection_IP::vrpn_Connection_IP(): Out of memory\n");
5981 strcpy(IP, NIC_IPaddress);
5989 listen_udp_sock = ::open_udp_socket(&listen_port_no, NIC_IPaddress);
5991 listen_tcp_sock = ::open_tcp_socket(&listen_port_no, NIC_IPaddress);
5994 connectionStatus =
BROKEN;
6000 connectionStatus =
LISTEN;
6003 printf(
"vrpn: Listening for requests on port %d\n", listen_port_no);
6008 if (listen(listen_tcp_sock, 1)) {
6009 fprintf(stderr,
"Couldn't listen on TCP listening socket.\n");
6010 connectionStatus =
BROKEN;
6014 flush_udp_socket(listen_udp_sock);
6020 const char *station_name,
int port,
const char *local_in_logfile_name,
6021 const char *local_out_logfile_name,
const char *remote_in_logfile_name,
6022 const char *remote_out_logfile_name,
const char *NIC_IPaddress,
6025 remote_in_logfile_name, remote_out_logfile_name, epa)
6037 if (NIC_IPaddress != NULL) {
6038 char *IP =
new char[strlen(NIC_IPaddress) + 1];
6042 "vrpn_Connection_IP::vrpn_Connection_IP(): Out of memory\n");
6045 strcpy(IP, NIC_IPaddress);
6050 isrsh = (strstr(station_name,
"x-vrsh:") ? VRPN_TRUE : VRPN_FALSE);
6051 istcp = (strstr(station_name,
"tcp:") ? VRPN_TRUE : VRPN_FALSE);
6056 endpoint = d_endpoints[0];
6065 if (!isrsh && !istcp) {
6071 "vrpn_Connection_IP: Can't get remote machine name!\n");
6072 connectionStatus =
BROKEN;
6093 "vrpn_Connection_IP: Can't Set up socket to lob UDP packets!\n");
6094 connectionStatus =
BROKEN;
6101 printf(
"vrpn_Connection_IP: Getting the TCP port to listen on\n");
6106 char local_host[64];
6112 local_host) == -1) {
6113 fprintf(stderr,
"vrpn_Connection_IP: Can't create listen socket\n");
6126 fprintf(stderr,
"vrpn_Connection_IP: Can't lob UDP request\n");
6151 fprintf(stderr,
"vrpn_Connection_IP: Can't poll for accept\n");
6152 connectionStatus =
BROKEN;
6162 printf(
"vrpn: Connection established on initial try\n");
6167 fprintf(stderr,
"vrpn_Connection_IP: " 6168 "Can't set up new connection!\n");
6182 fprintf(stderr,
"vrpn_Connection_IP: Can't get remote machine name " 6183 "for tcp: connection!\n");
6184 connectionStatus =
BROKEN;
6196 printf(
"vrpn_Connection_IP: Getting the TCP port to connect with.\n");
6206 "vrpn_Connection_IP: Can't create TCP connection.\n");
6215 fprintf(stderr,
"vrpn_Connection_IP: " 6216 "Can't set up new connection!\n");
6230 char *server_program;
6237 token = server_args;
6239 while ((token = strchr(token,
',')) != NULL) {
6243 endpoint->
d_tcpSocket = vrpn_start_server(machinename, server_program,
6244 server_args, NIC_IPaddress);
6245 if (machinename)
delete[](
char *)machinename;
6246 if (server_program)
delete[](
char *)server_program;
6247 if (server_args)
delete[](
char *)server_args;
6250 fprintf(stderr,
"vrpn_Connection_IP: " 6264 fprintf(stderr,
"vrpn_Connection_IP: " 6265 "Can't set up new connection!\n");
6267 connectionStatus =
BROKEN;
6303 for (i = 0; i < d_numEndpoints; i++) {
6304 if (d_endpoints[i]) {
6305 d_endpoints[i]->drop_connection();
6306 delete d_endpoints[i];
6310 #ifdef VRPN_USE_WINSOCK_SOCKETS 6312 if (WSACleanup() == SOCKET_ERROR) {
6313 fprintf(stderr,
"~vrpn_Connection_IP(): " 6314 "WSACleanup() failed with error code %d\n",
6318 #endif // VRPN_USE_WINSOCK_SOCKETS 6347 if (fullname == NULL) {
6351 size_t len = 1 + strcspn(fullname,
"@");
6352 char *tbuf =
new char[len];
6354 fprintf(stderr,
"vrpn_copy_service_name: Out of memory!\n");
6356 strncpy(tbuf, fullname, len - 1);
6366 int offset =
static_cast<int>(strcspn(fullname,
"@"));
6367 size_t len = strlen(fullname) - offset;
6370 len = strlen(fullname) + 1;
6372 char *tbuf =
new char[len];
6374 fprintf(stderr,
"vrpn_copy_service_name: Out of memory!\n");
6376 strncpy(tbuf, fullname + offset + 1, len - 1);
6389 if (!fp)
return NULL;
6391 if (!strncmp(fp,
"file://", 7)) {
6394 else if (!strncmp(fp,
"file:", 5)) {
6398 len = 1 + strlen(fp);
6399 filename =
new char[len];
6401 fprintf(stderr,
"vrpn_copy_file_name: Out of memory!\n");
6403 strncpy(filename, fp, len - 1);
6404 filename[len - 1] = 0;
6412 static int header_len(
const char *hostspecifier)
6416 if (!strncmp(hostspecifier,
"x-vrpn://", 9) ||
6417 !strncmp(hostspecifier,
"x-vrsh://", 9)) {
6420 else if (!strncmp(hostspecifier,
"x-vrpn:", 7) ||
6421 !strncmp(hostspecifier,
"x-vrsh:", 7)) {
6424 else if (!strncmp(hostspecifier,
"tcp://", 6)) {
6427 else if (!strncmp(hostspecifier,
"tcp:", 4)) {
6430 else if (!strncmp(hostspecifier,
"mpi://", 6)) {
6433 else if (!strncmp(hostspecifier,
"mpi:", 4)) {
6446 size_t nearoffset = 0;
6455 nearoffset = header_len(hostspecifier);
6460 faroffset = strcspn(hostspecifier + nearoffset,
":/");
6461 len = 1 + faroffset;
6463 tbuf =
new char[len];
6465 fprintf(stderr,
"vrpn_copy_machine_name: Out of memory!\n");
6468 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6483 pn += header_len(hostspecifier);
6485 pn = strrchr(pn,
':');
6496 size_t nearoffset = 0;
6501 nearoffset += header_len(hostspecifier);
6503 nearoffset += strcspn(hostspecifier + nearoffset,
"/");
6505 faroffset = strcspn(hostspecifier + nearoffset,
",");
6506 len = 1 + (faroffset ? faroffset : strlen(hostspecifier) - nearoffset);
6507 tbuf =
new char[len];
6510 fprintf(stderr,
"vrpn_copy_rsh_program: Out of memory!\n");
6512 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6521 size_t nearoffset = 0;
6526 nearoffset += header_len(hostspecifier);
6528 nearoffset += strcspn(hostspecifier + nearoffset,
"/");
6529 nearoffset += strcspn(hostspecifier + nearoffset,
",");
6530 faroffset = strlen(hostspecifier);
6531 len = 1 + faroffset - nearoffset;
6532 tbuf =
new char[len];
6535 fprintf(stderr,
"vrpn_copy_rsh_arguments: Out of memory!\n");
6537 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6553 size_t inputLength = strlen(specifier);
6554 size_t atSymbolIndex = strcspn(specifier,
"@");
6556 char *location = NULL;
6558 if (atSymbolIndex == inputLength) {
6560 location =
new char[inputLength + 1];
6561 strcpy(location, specifier);
6569 size_t len = strlen(location) + strlen(newServiceName);
6570 char *newSpecifier =
new char[len + 2];
6572 strcpy(newSpecifier, newServiceName);
6573 strcat(newSpecifier,
"@");
6574 strcat(newSpecifier, location);
6576 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) ...
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...
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.
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...
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 i...
#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...
virtual vrpn_bool connected(void) const
Returns vrpn_true if the connection has been established, vrpn_false if not (For a networkless connec...
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 g...
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)
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
vrpn_int32 udp_outbuf_size(void) const
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
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)
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...
const vrpn_int32 vrpn_CONNECTION_UDP_DESCRIPTION
SOCKET d_udpOutboundSocket
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...
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)
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...
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(). Create a connection - if server_name is not a file: name, makes an SDI-like connection to the named remote server (otherwise functions as a non-networked messaging hub). Port less than zero forces default. Currently, server_name is an extended URL that defaults to VRPN connections at the port, but can be file:: to read from a file. Other extensions should maintain this, so that VRPN uses URLs to name things that are to be connected to.
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 serve...
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_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...
vrpn_bool outbound_udp_open(void) const
True if the UDP outbound is open, False if not.
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
vrpn_float64 d_udpAlignedInbuf[vrpn_CONNECTION_UDP_BUFLEN/sizeof(vrpn_float64)+ 1]
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, not O(1000).
const vrpn_int32 vrpn_CONNECTION_TYPE_DESCRIPTION
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 va...
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)
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...
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...
vrpn_float64 d_tcpAlignedInbuf[vrpn_CONNECTION_TCP_BUFLEN/sizeof(vrpn_float64)+ 1]
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 serve...
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.
int local_sender_id(vrpn_int32 remote_sender) const
Returns the local mapping for the remote sender (-1 if none).
vrpn_int32 sender
Only if from sender.
class VRPN_API vrpn_Connection
int vrpn_noint_block_write(int outfile, const char buffer[], size_t length)
This routine will write a block to a file descriptor.
virtual vrpn_bool doing_okay(void) const
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)
char * vrpn_copy_machine_name(const char *hostspecifier)
virtual void drop_connection(void)=0
Should only be called by vrpn_Connection::drop_connection(), < since there's more housecleaning to do...
int local_type_id(vrpn_int32 remote_type) const
Returns the local mapping for the remote type (-1 if none).
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_Endpoint_IP(vrpn_TypeDispatcher *dispatcher, vrpn_int32 *connectedEndpointCounter)
vrpn_TranslationTable * d_senders
virtual const char * sender_name(vrpn_int32 sender)
Returns the name of the specified sender/type, or NULL if the parameter is invalid. Only works for user messages (type >= 0).
long & logMode(void)
Returns a reference so we can |= it.
int vrpn_noint_block_read(int infile, char buffer[], size_t length)
This routine will read in a block from the file descriptor.
char * vrpn_copy_rsh_program(const char *hostspecifier)
int handle_udp_messages(const timeval *timeout)
vrpn_int32 tcp_outbuf_size(void) const
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
virtual void init(void)
Called by all constructors.
#define vrpn_gettimeofday
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).
char * getName()
Allocates a new string and copies the log file name to it. < IMPORTANT: code calling this function is...
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.
int message_type_is_registered(const char *) const
Returns message type ID, or -1 if unregistered.
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 f...
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 endpoi...
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 End...
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...
virtual vrpn_bool doing_okay(void) const
Returns vrpn_true if the connection is okay, vrpn_false if not.
int write_vrpn_cookie(char *buffer, size_t length, long remote_log_mode)
Writes the magic cookie into buffer with given length.
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.
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...