aboutsummaryrefslogtreecommitdiff
path: root/nxcomp/Socket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'nxcomp/Socket.cpp')
-rw-r--r--nxcomp/Socket.cpp753
1 files changed, 0 insertions, 753 deletions
diff --git a/nxcomp/Socket.cpp b/nxcomp/Socket.cpp
deleted file mode 100644
index 28cb5646d..000000000
--- a/nxcomp/Socket.cpp
+++ /dev/null
@@ -1,753 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
-/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
-/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
-/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
-/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
-/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
-/* */
-/* NXCOMP, NX protocol compression and NX extensions to this software */
-/* are copyright of the aforementioned persons and companies. */
-/* */
-/* Redistribution and use of the present software is allowed according */
-/* to terms specified in the file LICENSE.nxcomp which comes in the */
-/* source distribution. */
-/* */
-/* All rights reserved. */
-/* */
-/* NOTE: This software has received contributions from various other */
-/* contributors, only the core maintainers and supporters are listed as */
-/* copyright holders. Please contact us, if you feel you should be listed */
-/* as copyright holder, as well. */
-/* */
-/**************************************************************************/
-
-#include <sys/types.h>
-#include <sys/utsname.h>
-
-#if defined(__CYGWIN32__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun)
-#include <netinet/in_systm.h>
-#endif
-
-#ifdef __sun
-#include <unistd.h>
-#include <sys/termios.h>
-#endif
-
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-
-#include <netdb.h>
-#include <fcntl.h>
-
-//
-// System specific defines.
-//
-
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun)
-#define SOL_IP IPPROTO_IP
-#endif
-
-#ifdef __sun
-#define INADDR_NONE ((unsigned int) -1)
-#endif
-
-//
-// The TIOCOUTQ ioctl is not implemented on Cygwin.
-// Note also that TIOCOUTQ and IPTOS_LOWDELAY are
-// disabled when running on MacOS/X.
-//
-
-#ifdef __CYGWIN32__
-#define TIOCOUTQ ((unsigned int) -1)
-#endif
-
-//
-// NX includes.
-//
-
-#include "Misc.h"
-#include "Socket.h"
-
-//
-// Set verbosity level.
-//
-
-#define PANIC
-#define WARNING
-#undef TEST
-#undef DEBUG
-
-//
-// Set this only once by querying OS details.
-//
-
-static int _kernelStep = -1;
-
-int GetKernelStep()
-{
- if (_kernelStep < 0)
- {
- //
- // At the moment only NX clients run on Win32
- // and MacOS/X so we are not really interested
- // in the relevant OS dependent functions.
- //
-
- #if defined(__CYGWIN32__) || defined(__APPLE__)
-
- _kernelStep = 0;
-
- #else
-
- struct utsname buffer;
-
- if (uname(&buffer) < 0)
- {
- #ifdef WARNING
- *logofs << "Socket: WARNING! Failed to get system info. Error is "
- << EGET() << " '" << ESTR() << "'.\n" << logofs_flush;
-
- *logofs << "Socket: WARNING! Assuming lowest system support.\n"
- << logofs_flush;
- #endif
-
- cerr << "Warning" << ": Failed to get system info. Error is "
- << EGET() << " '" << ESTR() << "'.\n";
-
- cerr << "Warning" << ": Assuming lowest system support.\n";
-
- _kernelStep = 0;
- }
- else
- {
- #ifdef TEST
- *logofs << "Socket: System is '" << buffer.sysname
- << "' nodename '" << buffer.nodename << "' release '"
- << buffer.release << "'.\n" << logofs_flush;
-
- *logofs << "Socket: Version is '" << buffer.version << "' machine '"
- << buffer.machine << "'.\n" << logofs_flush;
- #endif
-
- //
- // Should test support on other operating systems.
- //
-
- if (strcmp(buffer.sysname, "Linux") == 0)
- {
- if (strncmp(buffer.release, "2.0.", 4) == 0 ||
- strncmp(buffer.release, "2.2.", 4) == 0)
- {
- #ifdef TEST
- *logofs << "Socket: Assuming level 2 system support.\n"
- << logofs_flush;
- #endif
-
- _kernelStep = 2;
- }
- else
- {
- #ifdef TEST
- *logofs << "Socket: Assuming level 3 system support.\n"
- << logofs_flush;
- #endif
-
- _kernelStep = 3;
- }
- }
- else if (strcmp(buffer.sysname, "SunOS") == 0)
- {
- #ifdef TEST
- *logofs << "Socket: Assuming level 1 system support.\n"
- << logofs_flush;
- #endif
-
- _kernelStep = 1;
- }
- else
- {
- #ifdef TEST
- *logofs << "Socket: Assuming level 0 system support.\n"
- << logofs_flush;
- #endif
-
- _kernelStep = 0;
- }
- }
-
- #endif /* #if defined(__CYGWIN32__) || defined(__APPLE__) */
- }
-
- return _kernelStep;
-}
-
-int SetReuseAddress(int fd)
-{
- int flag = 1;
-
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- (char *) &flag, sizeof(flag)) < 0)
- {
- #ifdef PANIC
- *logofs << "Socket: PANIC! Failed to set SO_REUSEADDR flag on FD#"
- << fd << ". Error is " << EGET() << " '" << ESTR() << "'.\n"
- << logofs_flush;
- #endif
-
- cerr << "Error" << ": Failed to set SO_REUSEADDR flag on FD#"
- << fd << ". Error is " << EGET() << " '" << ESTR()
- << "'.\n";
-
- return -1;
- }
- #ifdef TEST
- else
- {
- *logofs << "Socket: Set SO_REUSEADDR flag on FD#"
- << fd << ".\n" << logofs_flush;
- }
- #endif
-
- return 1;
-}
-
-int SetNonBlocking(int fd, int value)
-{
- int flags = fcntl(fd, F_GETFL);
-
- if (flags >= 0)
- {
- if (value == 0)
- {
- flags &= ~O_NONBLOCK;
- }
- else
- {
- flags |= O_NONBLOCK;
- }
- }
-
- if (flags < 0 || fcntl(fd, F_SETFL, flags) < 0)
- {
- #ifdef PANIC
- *logofs << "Socket: PANIC! Failed to set O_NONBLOCK flag on FD#"
- << fd << " to " << value << ". Error is " << EGET()
- << " '" << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Failed to set O_NONBLOCK flag on FD#"
- << fd << " to " << value << ". Error is " << EGET()
- << " '" << ESTR() << "'.\n";
-
- return -1;
- }
- #ifdef TEST
- else
- {
- *logofs << "Socket: Set O_NONBLOCK flag on FD#"
- << fd << " to " << value << ".\n"
- << logofs_flush;
- }
- #endif
-
- return 1;
-}
-
-int SetLingerTimeout(int fd, int timeout)
-{
- struct linger linger_value;
-
- if (timeout > 0)
- {
- linger_value.l_onoff = 1;
- linger_value.l_linger = timeout;
- }
- else
- {
- linger_value.l_onoff = 0;
- linger_value.l_linger = 0;
- }
-
- if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger_value, sizeof(linger_value)) < 0)
- {
- #ifdef PANIC
- *logofs << "Socket: PANIC! Failed to set SO_LINGER values to "
- << linger_value.l_onoff << " and " << linger_value.l_linger
- << " on FD#" << fd << ". Error is " << EGET() << " '"
- << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Failed to set SO_LINGER values to "
- << linger_value.l_onoff << " and " << linger_value.l_linger
- << " on FD#" << fd << ". Error is " << EGET() << " '"
- << ESTR() << "'.\n";
-
- return -1;
- }
- #ifdef TEST
- else
- {
- *logofs << "Socket: Set SO_LINGER values to "
- << linger_value.l_onoff << " and " << linger_value.l_linger
- << " on FD#" << fd << ".\n" << logofs_flush;
- }
- #endif
-
- return 1;
-}
-
-int SetSendBuffer(int fd, int size)
-{
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0)
- {
- #ifdef PANIC
- *logofs << "Socket: PANIC! Failed to set SO_SNDBUF size to "
- << size << " on FD#" << fd << ". Error is "
- << EGET() << " '" << ESTR() << "'.\n"
- << logofs_flush;
- #endif
-
- cerr << "Error" << ": Failed to set SO_SNDBUF size to "
- << size << " on FD#" << fd << ". Error is "
- << EGET() << " '" << ESTR() << "'.\n";
-
- return -1;
- }
- #ifdef TEST
- else
- {
- *logofs << "Socket: Set SO_SNDBUF on FD#" << fd
- << " to " << size << " bytes.\n"
- << logofs_flush;
- }
- #endif
-
- return 1;
-}
-
-int SetReceiveBuffer(int fd, int size)
-{
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) < 0)
- {
- #ifdef PANIC
- *logofs << "Socket: PANIC! Failed to set SO_RCVBUF size to "
- << size << " on FD#" << fd << ". Error is "
- << EGET() << " '" << ESTR() << "'.\n"
- << logofs_flush;
- #endif
-
- cerr << "Error" << ": Failed to set SO_RCVBUF size to "
- << size << " on FD#" << fd << ". Error is "
- << EGET() << " '" << ESTR() << "'.\n";
-
- return -1;
- }
- #ifdef TEST
- else
- {
- *logofs << "Socket: Set SO_RCVBUF on FD#" << fd
- << " to " << size << " bytes.\n"
- << logofs_flush;
- }
- #endif
-
- return 1;
-}
-
-int SetNoDelay(int fd, int value)
-{
- int result = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value));
-
- if (result == 0)
- {
- result = 1;
- }
- else if (result < 0)
- {
- //
- // Is it become a different error on
- // Mac OSX 10.4?
- //
-
- #if defined(__APPLE__)
-
- result = 0;
-
- #endif
-
- #if defined(__sun)
-
- if (EGET() == ENOPROTOOPT)
- {
- result = 0;
- }
-
- #endif
-
- #if !defined(__APPLE__) && !defined(__sun)
-
- if (EGET() == EOPNOTSUPP)
- {
- result = 0;
- }
-
- #endif
- }
-
- if (result < 0)
- {
- #ifdef PANIC
- *logofs << "Socket: PANIC! Failed to set TCP_NODELAY flag on "
- << "FD#" << fd << " to " << value << ". Error is "
- << EGET() << " '" << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Failed to set TCP_NODELAY flag on "
- << "FD#" << fd << " to " << value << ". Error is "
- << EGET() << " '" << ESTR() << "'.\n";
- }
- #ifdef TEST
- else if (result == 0)
- {
- #ifdef TEST
- *logofs << "Socket: Option TCP_NODELAY not supported "
- << "on FD#" << fd << ".\n" << logofs_flush;
- #endif
- }
- else
- {
- *logofs << "Socket: Set TCP_NODELAY flag on FD#"
- << fd << " to " << value << ".\n"
- << logofs_flush;
- }
- #endif
-
- return result;
-}
-
-int SetKeepAlive(int fd)
-{
- int flag = 1;
-
- if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof(flag)) < 0)
- {
- #ifdef PANIC
- *logofs << "Socket: PANIC! Failed to set SO_KEEPALIVE flag on "
- << "FD#" << fd << ". Error is " << EGET() << " '"
- << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Failed to set SO_KEEPALIVE flag on "
- << "FD#" << fd << ". Error is " << EGET() << " '"
- << ESTR() << "'.\n";
-
- return -1;
- }
- #ifdef TEST
- else
- {
- *logofs << "Socket: Set SO_KEEPALIVE flag on FD#"
- << fd << ".\n" << logofs_flush;
- }
- #endif
-
- return 1;
-}
-
-int SetLowDelay(int fd)
-{
- if (_kernelStep < 0)
- {
- GetKernelStep();
- }
-
- switch (_kernelStep)
- {
- case 3:
- case 2:
- case 1:
- {
- int flag = IPTOS_LOWDELAY;
-
- if (setsockopt(fd, SOL_IP, IP_TOS, &flag, sizeof(flag)) < 0)
- {
- if (EGET() == EOPNOTSUPP)
- {
- #ifdef TEST
- *logofs << "Socket: Option IPTOS_LOWDELAY not supported "
- << "on FD#" << fd << ".\n" << logofs_flush;
- #endif
-
- return 0;
- }
- else
- {
- #ifdef WARNING
- *logofs << "Socket: WARNING! Failed to set IPTOS_LOWDELAY flag on "
- << "FD#" << fd << ". Error is " << EGET() << " '" << ESTR()
- << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Warning" << ": Failed to set IPTOS_LOWDELAY flag on "
- << "FD#" << fd << ". Error is " << EGET() << " '" << ESTR()
- << "'.\n";
-
- return -1;
- }
- }
- #ifdef TEST
- else
- {
- *logofs << "Socket: Set IPTOS_LOWDELAY flag on FD#"
- << fd << ".\n" << logofs_flush;
- }
- #endif
-
- return 1;
- }
- default:
- {
- #ifdef TEST
- *logofs << "Socket: Option IPTOS_LOWDELAY not "
- << "supported on FD#" << fd << ".\n"
- << logofs_flush;
- #endif
-
- return 0;
- }
- }
-}
-
-int SetCloseOnExec(int fd)
-{
- if (fcntl(fd, F_SETFD, 1) != 0)
- {
- #ifdef TEST
- *logofs << "NXClient: PANIC! Cannot set close-on-exec "
- << "on FD#" << fd << ". Error is " << EGET()
- << " '" << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Cannot set close-on-exec on FD#"
- << fd << ". Error is " << EGET() << " '" << ESTR()
- << "'.\n";
-
- return -1;
- }
-
- return 1;
-}
-
-int GetBytesReadable(int fd)
-{
- long readable = 0;
-
- //
- // It may fail, for example at session
- // shutdown.
- //
-
- if (ioctl(fd, FIONREAD, &readable) < 0)
- {
- #ifdef TEST
- *logofs << "Socket: PANIC! Failed to get bytes readable "
- << "from FD#" << fd << ". Error is " << EGET()
- << " '" << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- return -1;
- }
-
- #ifdef TEST
- *logofs << "Socket: Returning " << (int) readable
- << " bytes readable on FD#" << fd << ".\n"
- << logofs_flush;
- #endif
-
- return (int) readable;
-}
-
-int GetBytesWritable(int fd)
-{
- if (_kernelStep < 0)
- {
- GetKernelStep();
- }
-
- long writable;
-
- switch (_kernelStep)
- {
- case 3:
- {
- //
- // TODO: Should query the real size
- // of the TCP write buffer.
- //
-
- writable = 16384 - GetBytesQueued(fd);
-
- if (writable < 0)
- {
- writable = 0;
- }
-
- break;
- }
- case 2:
- {
- if (ioctl(fd, TIOCOUTQ, (void *) &writable) < 0)
- {
- #ifdef PANIC
- *logofs << "Socket: PANIC! Failed to get bytes writable "
- << "on FD#" << fd << ". Error is " << EGET()
- << " '" << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Failed to get bytes writable "
- << "on FD#" << fd << ". Error is " << EGET()
- << " '" << ESTR() << "'.\n";
-
- return -1;
- }
-
- break;
- }
- default:
- {
- #ifdef TEST
- *logofs << "Socket: Option TIOCOUTQ not supported "
- << "on FD#" << fd << ",\n" << logofs_flush;
- #endif
-
- //
- // TODO: Should query the real size
- // of the TCP write buffer.
- //
-
- writable = 16384;
-
- break;
- }
- }
-
- #ifdef TEST
- *logofs << "Socket: Returning " << writable
- << " bytes writable on FD#" << fd
- << ".\n" << logofs_flush;
- #endif
-
- return (int) writable;
-}
-
-int GetBytesQueued(int fd)
-{
- //
- // The TIOCOUTQ ioctl is not implemented on Cygwin
- // and returns the space available on Linux Kernels
- // 2.0 and 2.2 (like current MIPS for PS/2).
- //
-
- if (_kernelStep < 0)
- {
- GetKernelStep();
- }
-
- long queued;
-
- switch (_kernelStep)
- {
- case 3:
- {
- if (ioctl(fd, TIOCOUTQ, (void *) &queued) < 0)
- {
- #ifdef PANIC
- *logofs << "Socket: PANIC! Failed to get bytes queued "
- << "on FD#" << fd << ". Error is " << EGET()
- << " '" << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Failed to get bytes queued "
- << "on FD#" << fd << ". Error is " << EGET()
- << " '" << ESTR() << "'.\n";
-
- return -1;
- }
-
- break;
- }
- case 2:
- {
- //
- // TODO: Should query the real size
- // of the TCP write buffer.
- //
-
- queued = 16384 - GetBytesWritable(fd);
-
- if (queued < 0)
- {
- queued = 0;
- }
-
- break;
- }
- default:
- {
- #ifdef TEST
- *logofs << "Socket: Option TIOCOUTQ not supported "
- << "on FD#" << fd << ",\n" << logofs_flush;
- #endif
-
- queued = 0;
-
- break;
- }
- }
-
- #ifdef TEST
- *logofs << "Socket: Returning " << queued
- << " bytes queued on FD#" << fd
- << ".\n" << logofs_flush;
- #endif
-
- return (int) queued;
-}
-
-int GetHostAddress(const char *name)
-{
- hostent *host = gethostbyname(name);
-
- if (host == NULL)
- {
- //
- // On some Unices gethostbyname() doesn't
- // accept IP addresses, so try inet_addr.
- //
-
- IN_ADDR_T address = inet_addr(name);
-
- if (address == INADDR_NONE)
- {
- #ifdef PANIC
- *logofs << "Socket: PANIC! Failed to resolve address of '"
- << name << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Failed to resolve address of '"
- << name << "'.\n";
-
- return 0;
- }
-
- return (int) address;
- }
- else
- {
- return (*((int *) host -> h_addr_list[0]));
- }
-}