summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--PracticalSocket.cpp412
-rw-r--r--PracticalSocket.h371
-rw-r--r--anytun.cpp6
-rw-r--r--tunDevice.cpp2
5 files changed, 791 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index c94b0e0..03af359 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,7 @@ OPENVPNDEPS = openvpn/tun.o \
-OBJS = anytun.o tunDevice.o buffer.o package.o cypher.o authAlgo.o $(OPENVPNDEPS)
+OBJS = anytun.o tunDevice.o buffer.o package.o cypher.o authAlgo.o PracticalSocket.o $(OPENVPNDEPS)
EXECUTABLE = anytun
all: $(EXECUTABLE)
@@ -54,6 +54,9 @@ cypher.o: cypher.cpp cypher.h buffer.h
authAlgo.o: authAlgo.cpp authAlgo.h buffer.h
$(C++) $(CCFLAGS) $< -c
+PracticalSocket.o: PracticalSocket.cpp PracticalSocket.h
+ $(C++) $(CCFLAGS) $< -c
+
anytun.o: anytun.cpp
$(C++) $(CCFLAGS) $< -c
diff --git a/PracticalSocket.cpp b/PracticalSocket.cpp
new file mode 100644
index 0000000..658bc6e
--- /dev/null
+++ b/PracticalSocket.cpp
@@ -0,0 +1,412 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// this is from: http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/practical/
+// and this is their header:
+/*
+ * C++ sockets on Unix and Windows
+ * Copyright (C) 2002
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "PracticalSocket.h"
+
+#ifdef WIN32
+ #include <winsock.h> // For socket(), connect(), send(), and recv()
+ typedef int socklen_t;
+ typedef char raw_type; // Type used for raw data on this platform
+#else
+ #include <sys/types.h> // For data types
+ #include <sys/socket.h> // For socket(), connect(), send(), and recv()
+ #include <netdb.h> // For gethostbyname()
+ #include <arpa/inet.h> // For inet_addr()
+ #include <unistd.h> // For close()
+ #include <netinet/in.h> // For sockaddr_in
+ typedef void raw_type; // Type used for raw data on this platform
+#endif
+
+#include <errno.h> // For errno
+
+using namespace std;
+
+#ifdef WIN32
+static bool initialized = false;
+#endif
+
+// SocketException Code
+
+SocketException::SocketException(const string &message, bool inclSysMsg)
+ throw() : userMessage(message) {
+ if (inclSysMsg) {
+ userMessage.append(": ");
+ userMessage.append(strerror(errno));
+ }
+}
+
+SocketException::~SocketException() throw() {
+}
+
+const char *SocketException::what() const throw() {
+ return userMessage.c_str();
+}
+
+// Function to fill in address structure given an address and port
+static void fillAddr(const string &address, unsigned short port,
+ sockaddr_in &addr) {
+ memset(&addr, 0, sizeof(addr)); // Zero out address structure
+ addr.sin_family = AF_INET; // Internet address
+
+ hostent *host; // Resolve name
+ if ((host = gethostbyname(address.c_str())) == NULL) {
+ // strerror() will not work for gethostbyname() and hstrerror()
+ // is supposedly obsolete
+ throw SocketException("Failed to resolve name (gethostbyname())");
+ }
+ addr.sin_addr.s_addr = *((unsigned long *) host->h_addr_list[0]);
+
+ addr.sin_port = htons(port); // Assign port in network byte order
+}
+
+// Socket Code
+
+Socket::Socket(int type, int protocol) throw(SocketException) {
+ #ifdef WIN32
+ if (!initialized) {
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD(2, 0); // Request WinSock v2.0
+ if (WSAStartup(wVersionRequested, &wsaData) != 0) { // Load WinSock DLL
+ throw SocketException("Unable to load WinSock DLL");
+ }
+ initialized = true;
+ }
+ #endif
+
+ // Make a new socket
+ if ((sockDesc = socket(PF_INET, type, protocol)) < 0) {
+ throw SocketException("Socket creation failed (socket())", true);
+ }
+}
+
+Socket::Socket(int sockDesc) {
+ this->sockDesc = sockDesc;
+}
+
+Socket::~Socket() {
+ #ifdef WIN32
+ ::closesocket(sockDesc);
+ #else
+ ::close(sockDesc);
+ #endif
+ sockDesc = -1;
+}
+
+string Socket::getLocalAddress() throw(SocketException) {
+ sockaddr_in addr;
+ unsigned int addr_len = sizeof(addr);
+
+ if (getsockname(sockDesc, (sockaddr *) &addr, (socklen_t *) &addr_len) < 0) {
+ throw SocketException("Fetch of local address failed (getsockname())", true);
+ }
+ return inet_ntoa(addr.sin_addr);
+}
+
+unsigned short Socket::getLocalPort() throw(SocketException) {
+ sockaddr_in addr;
+ unsigned int addr_len = sizeof(addr);
+
+ if (getsockname(sockDesc, (sockaddr *) &addr, (socklen_t *) &addr_len) < 0) {
+ throw SocketException("Fetch of local port failed (getsockname())", true);
+ }
+ return ntohs(addr.sin_port);
+}
+
+void Socket::setLocalPort(unsigned short localPort) throw(SocketException) {
+ // Bind the socket to its port
+ sockaddr_in localAddr;
+ memset(&localAddr, 0, sizeof(localAddr));
+ localAddr.sin_family = AF_INET;
+ localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ localAddr.sin_port = htons(localPort);
+
+ if (bind(sockDesc, (sockaddr *) &localAddr, sizeof(sockaddr_in)) < 0) {
+ throw SocketException("Set of local port failed (bind())", true);
+ }
+}
+
+void Socket::setLocalAddressAndPort(const string &localAddress,
+ unsigned short localPort) throw(SocketException) {
+ // Get the address of the requested host
+ sockaddr_in localAddr;
+ fillAddr(localAddress, localPort, localAddr);
+
+ if (bind(sockDesc, (sockaddr *) &localAddr, sizeof(sockaddr_in)) < 0) {
+ throw SocketException("Set of local address and port failed (bind())", true);
+ }
+}
+
+void Socket::cleanUp() throw(SocketException) {
+ #ifdef WIN32
+ if (WSACleanup() != 0) {
+ throw SocketException("WSACleanup() failed");
+ }
+ #endif
+}
+
+unsigned short Socket::resolveService(const string &service,
+ const string &protocol) {
+ struct servent *serv; /* Structure containing service information */
+
+ if ((serv = getservbyname(service.c_str(), protocol.c_str())) == NULL)
+ return atoi(service.c_str()); /* Service is port number */
+ else
+ return ntohs(serv->s_port); /* Found port (network byte order) by name */
+}
+
+// CommunicatingSocket Code
+
+CommunicatingSocket::CommunicatingSocket(int type, int protocol)
+ throw(SocketException) : Socket(type, protocol) {
+}
+
+CommunicatingSocket::CommunicatingSocket(int newConnSD) : Socket(newConnSD) {
+}
+
+void CommunicatingSocket::connect(const string &foreignAddress,
+ unsigned short foreignPort) throw(SocketException) {
+ // Get the address of the requested host
+ sockaddr_in destAddr;
+ fillAddr(foreignAddress, foreignPort, destAddr);
+
+ // Try to connect to the given port
+ if (::connect(sockDesc, (sockaddr *) &destAddr, sizeof(destAddr)) < 0) {
+ throw SocketException("Connect failed (connect())", true);
+ }
+}
+
+void CommunicatingSocket::send(const void *buffer, int bufferLen)
+ throw(SocketException) {
+ if (::send(sockDesc, (raw_type *) buffer, bufferLen, 0) < 0) {
+ throw SocketException("Send failed (send())", true);
+ }
+}
+
+int CommunicatingSocket::recv(void *buffer, int bufferLen)
+ throw(SocketException) {
+ int rtn;
+ if ((rtn = ::recv(sockDesc, (raw_type *) buffer, bufferLen, 0)) < 0) {
+ throw SocketException("Received failed (recv())", true);
+ }
+
+ return rtn;
+}
+
+string CommunicatingSocket::getForeignAddress()
+ throw(SocketException) {
+ sockaddr_in addr;
+ unsigned int addr_len = sizeof(addr);
+
+ if (getpeername(sockDesc, (sockaddr *) &addr,(socklen_t *) &addr_len) < 0) {
+ throw SocketException("Fetch of foreign address failed (getpeername())", true);
+ }
+ return inet_ntoa(addr.sin_addr);
+}
+
+unsigned short CommunicatingSocket::getForeignPort() throw(SocketException) {
+ sockaddr_in addr;
+ unsigned int addr_len = sizeof(addr);
+
+ if (getpeername(sockDesc, (sockaddr *) &addr, (socklen_t *) &addr_len) < 0) {
+ throw SocketException("Fetch of foreign port failed (getpeername())", true);
+ }
+ return ntohs(addr.sin_port);
+}
+
+// TCPSocket Code
+
+TCPSocket::TCPSocket()
+ throw(SocketException) : CommunicatingSocket(SOCK_STREAM,
+ IPPROTO_TCP) {
+}
+
+TCPSocket::TCPSocket(const string &foreignAddress, unsigned short foreignPort)
+ throw(SocketException) : CommunicatingSocket(SOCK_STREAM, IPPROTO_TCP) {
+ connect(foreignAddress, foreignPort);
+}
+
+TCPSocket::TCPSocket(int newConnSD) : CommunicatingSocket(newConnSD) {
+}
+
+// TCPServerSocket Code
+
+TCPServerSocket::TCPServerSocket(unsigned short localPort, int queueLen)
+ throw(SocketException) : Socket(SOCK_STREAM, IPPROTO_TCP) {
+ setLocalPort(localPort);
+ setListen(queueLen);
+}
+
+TCPServerSocket::TCPServerSocket(const string &localAddress,
+ unsigned short localPort, int queueLen)
+ throw(SocketException) : Socket(SOCK_STREAM, IPPROTO_TCP) {
+ setLocalAddressAndPort(localAddress, localPort);
+ setListen(queueLen);
+}
+
+TCPSocket *TCPServerSocket::accept() throw(SocketException) {
+ int newConnSD;
+ if ((newConnSD = ::accept(sockDesc, NULL, 0)) < 0) {
+ throw SocketException("Accept failed (accept())", true);
+ }
+
+ return new TCPSocket(newConnSD);
+}
+
+void TCPServerSocket::setListen(int queueLen) throw(SocketException) {
+ if (listen(sockDesc, queueLen) < 0) {
+ throw SocketException("Set listening socket failed (listen())", true);
+ }
+}
+
+// UDPSocket Code
+
+UDPSocket::UDPSocket() throw(SocketException) : CommunicatingSocket(SOCK_DGRAM,
+ IPPROTO_UDP) {
+ setBroadcast();
+}
+
+UDPSocket::UDPSocket(unsigned short localPort) throw(SocketException) :
+ CommunicatingSocket(SOCK_DGRAM, IPPROTO_UDP) {
+ setLocalPort(localPort);
+ setBroadcast();
+}
+
+UDPSocket::UDPSocket(const string &localAddress, unsigned short localPort)
+ throw(SocketException) : CommunicatingSocket(SOCK_DGRAM, IPPROTO_UDP) {
+ setLocalAddressAndPort(localAddress, localPort);
+ setBroadcast();
+}
+
+void UDPSocket::setBroadcast() {
+ // If this fails, we'll hear about it when we try to send. This will allow
+ // system that cannot broadcast to continue if they don't plan to broadcast
+ int broadcastPermission = 1;
+ setsockopt(sockDesc, SOL_SOCKET, SO_BROADCAST,
+ (raw_type *) &broadcastPermission, sizeof(broadcastPermission));
+}
+
+void UDPSocket::disconnect() throw(SocketException) {
+ sockaddr_in nullAddr;
+ memset(&nullAddr, 0, sizeof(nullAddr));
+ nullAddr.sin_family = AF_UNSPEC;
+
+ // Try to disconnect
+ if (::connect(sockDesc, (sockaddr *) &nullAddr, sizeof(nullAddr)) < 0) {
+ #ifdef WIN32
+ if (errno != WSAEAFNOSUPPORT) {
+ #else
+ if (errno != EAFNOSUPPORT) {
+ #endif
+ throw SocketException("Disconnect failed (connect())", true);
+ }
+ }
+}
+
+void UDPSocket::sendTo(const void *buffer, int bufferLen,
+ const string &foreignAddress, unsigned short foreignPort)
+ throw(SocketException) {
+ sockaddr_in destAddr;
+ fillAddr(foreignAddress, foreignPort, destAddr);
+
+ // Write out the whole buffer as a single message.
+ if (sendto(sockDesc, (raw_type *) buffer, bufferLen, 0,
+ (sockaddr *) &destAddr, sizeof(destAddr)) != bufferLen) {
+ throw SocketException("Send failed (sendto())", true);
+ }
+}
+
+int UDPSocket::recvFrom(void *buffer, int bufferLen, string &sourceAddress,
+ unsigned short &sourcePort) throw(SocketException) {
+ sockaddr_in clntAddr;
+ socklen_t addrLen = sizeof(clntAddr);
+ int rtn;
+ if ((rtn = recvfrom(sockDesc, (raw_type *) buffer, bufferLen, 0,
+ (sockaddr *) &clntAddr, (socklen_t *) &addrLen)) < 0) {
+ throw SocketException("Receive failed (recvfrom())", true);
+ }
+ sourceAddress = inet_ntoa(clntAddr.sin_addr);
+ sourcePort = ntohs(clntAddr.sin_port);
+
+ return rtn;
+}
+
+void UDPSocket::setMulticastTTL(unsigned char multicastTTL) throw(SocketException) {
+ if (setsockopt(sockDesc, IPPROTO_IP, IP_MULTICAST_TTL,
+ (raw_type *) &multicastTTL, sizeof(multicastTTL)) < 0) {
+ throw SocketException("Multicast TTL set failed (setsockopt())", true);
+ }
+}
+
+void UDPSocket::joinGroup(const string &multicastGroup) throw(SocketException) {
+ struct ip_mreq multicastRequest;
+
+ multicastRequest.imr_multiaddr.s_addr = inet_addr(multicastGroup.c_str());
+ multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);
+ if (setsockopt(sockDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (raw_type *) &multicastRequest,
+ sizeof(multicastRequest)) < 0) {
+ throw SocketException("Multicast group join failed (setsockopt())", true);
+ }
+}
+
+void UDPSocket::leaveGroup(const string &multicastGroup) throw(SocketException) {
+ struct ip_mreq multicastRequest;
+
+ multicastRequest.imr_multiaddr.s_addr = inet_addr(multicastGroup.c_str());
+ multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);
+ if (setsockopt(sockDesc, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ (raw_type *) &multicastRequest,
+ sizeof(multicastRequest)) < 0) {
+ throw SocketException("Multicast group leave failed (setsockopt())", true);
+ }
+}
diff --git a/PracticalSocket.h b/PracticalSocket.h
new file mode 100644
index 0000000..dcb39a9
--- /dev/null
+++ b/PracticalSocket.h
@@ -0,0 +1,371 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// this is from: http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/practical/
+// and this is their header:
+/*
+ * C++ sockets on Unix and Windows
+ * Copyright (C) 2002
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __PRACTICALSOCKET_INCLUDED__
+#define __PRACTICALSOCKET_INCLUDED__
+
+#include <string> // For string
+#include <exception> // For exception class
+
+using namespace std;
+
+/**
+ * Signals a problem with the execution of a socket call.
+ */
+class SocketException : public exception {
+public:
+ /**
+ * Construct a SocketException with a explanatory message.
+ * @param message explanatory message
+ * @param incSysMsg true if system message (from strerror(errno))
+ * should be postfixed to the user provided message
+ */
+ SocketException(const string &message, bool inclSysMsg = false) throw();
+
+ /**
+ * Provided just to guarantee that no exceptions are thrown.
+ */
+ ~SocketException() throw();
+
+ /**
+ * Get the exception message
+ * @return exception message
+ */
+ const char *what() const throw();
+
+private:
+ string userMessage; // Exception message
+};
+
+/**
+ * Base class representing basic communication endpoint
+ */
+class Socket {
+public:
+ /**
+ * Close and deallocate this socket
+ */
+ ~Socket();
+
+ /**
+ * Get the local address
+ * @return local address of socket
+ * @exception SocketException thrown if fetch fails
+ */
+ string getLocalAddress() throw(SocketException);
+
+ /**
+ * Get the local port
+ * @return local port of socket
+ * @exception SocketException thrown if fetch fails
+ */
+ unsigned short getLocalPort() throw(SocketException);
+
+ /**
+ * Set the local port to the specified port and the local address
+ * to any interface
+ * @param localPort local port
+ * @exception SocketException thrown if setting local port fails
+ */
+ void setLocalPort(unsigned short localPort) throw(SocketException);
+
+ /**
+ * Set the local port to the specified port and the local address
+ * to the specified address. If you omit the port, a random port
+ * will be selected.
+ * @param localAddress local address
+ * @param localPort local port
+ * @exception SocketException thrown if setting local port or address fails
+ */
+ void setLocalAddressAndPort(const string &localAddress,
+ unsigned short localPort = 0) throw(SocketException);
+
+ /**
+ * If WinSock, unload the WinSock DLLs; otherwise do nothing. We ignore
+ * this in our sample client code but include it in the library for
+ * completeness. If you are running on Windows and you are concerned
+ * about DLL resource consumption, call this after you are done with all
+ * Socket instances. If you execute this on Windows while some instance of
+ * Socket exists, you are toast. For portability of client code, this is
+ * an empty function on non-Windows platforms so you can always include it.
+ * @param buffer buffer to receive the data
+ * @param bufferLen maximum number of bytes to read into buffer
+ * @return number of bytes read, 0 for EOF, and -1 for error
+ * @exception SocketException thrown WinSock clean up fails
+ */
+ static void cleanUp() throw(SocketException);
+
+ /**
+ * Resolve the specified service for the specified protocol to the
+ * corresponding port number in host byte order
+ * @param service service to resolve (e.g., "http")
+ * @param protocol protocol of service to resolve. Default is "tcp".
+ */
+ static unsigned short resolveService(const string &service,
+ const string &protocol = "tcp");
+
+private:
+ // Prevent the user from trying to use value semantics on this object
+ Socket(const Socket &sock);
+ void operator=(const Socket &sock);
+
+protected:
+ int sockDesc; // Socket descriptor
+ Socket(int type, int protocol) throw(SocketException);
+ Socket(int sockDesc);
+};
+
+/**
+ * Socket which is able to connect, send, and receive
+ */
+class CommunicatingSocket : public Socket {
+public:
+ /**
+ * Establish a socket connection with the given foreign
+ * address and port
+ * @param foreignAddress foreign address (IP address or name)
+ * @param foreignPort foreign port
+ * @exception SocketException thrown if unable to establish connection
+ */
+ void connect(const string &foreignAddress, unsigned short foreignPort)
+ throw(SocketException);
+
+ /**
+ * Write the given buffer to this socket. Call connect() before
+ * calling send()
+ * @param buffer buffer to be written
+ * @param bufferLen number of bytes from buffer to be written
+ * @exception SocketException thrown if unable to send data
+ */
+ void send(const void *buffer, int bufferLen) throw(SocketException);
+
+ /**
+ * Read into the given buffer up to bufferLen bytes data from this
+ * socket. Call connect() before calling recv()
+ * @param buffer buffer to receive the data
+ * @param bufferLen maximum number of bytes to read into buffer
+ * @return number of bytes read, 0 for EOF, and -1 for error
+ * @exception SocketException thrown if unable to receive data
+ */
+ int recv(void *buffer, int bufferLen) throw(SocketException);
+
+ /**
+ * Get the foreign address. Call connect() before calling recv()
+ * @return foreign address
+ * @exception SocketException thrown if unable to fetch foreign address
+ */
+ string getForeignAddress() throw(SocketException);
+
+ /**
+ * Get the foreign port. Call connect() before calling recv()
+ * @return foreign port
+ * @exception SocketException thrown if unable to fetch foreign port
+ */
+ unsigned short getForeignPort() throw(SocketException);
+
+protected:
+ CommunicatingSocket(int type, int protocol) throw(SocketException);
+ CommunicatingSocket(int newConnSD);
+};
+
+/**
+ * TCP socket for communication with other TCP sockets
+ */
+class TCPSocket : public CommunicatingSocket {
+public:
+ /**
+ * Construct a TCP socket with no connection
+ * @exception SocketException thrown if unable to create TCP socket
+ */
+ TCPSocket() throw(SocketException);
+
+ /**
+ * Construct a TCP socket with a connection to the given foreign address
+ * and port
+ * @param foreignAddress foreign address (IP address or name)
+ * @param foreignPort foreign port
+ * @exception SocketException thrown if unable to create TCP socket
+ */
+ TCPSocket(const string &foreignAddress, unsigned short foreignPort)
+ throw(SocketException);
+
+private:
+ // Access for TCPServerSocket::accept() connection creation
+ friend class TCPServerSocket;
+ TCPSocket(int newConnSD);
+};
+
+/**
+ * TCP socket class for servers
+ */
+class TCPServerSocket : public Socket {
+public:
+ /**
+ * Construct a TCP socket for use with a server, accepting connections
+ * on the specified port on any interface
+ * @param localPort local port of server socket, a value of zero will
+ * give a system-assigned unused port
+ * @param queueLen maximum queue length for outstanding
+ * connection requests (default 5)
+ * @exception SocketException thrown if unable to create TCP server socket
+ */
+ TCPServerSocket(unsigned short localPort, int queueLen = 5)
+ throw(SocketException);
+
+ /**
+ * Construct a TCP socket for use with a server, accepting connections
+ * on the specified port on the interface specified by the given address
+ * @param localAddress local interface (address) of server socket
+ * @param localPort local port of server socket
+ * @param queueLen maximum queue length for outstanding
+ * connection requests (default 5)
+ * @exception SocketException thrown if unable to create TCP server socket
+ */
+ TCPServerSocket(const string &localAddress, unsigned short localPort,
+ int queueLen = 5) throw(SocketException);
+
+ /**
+ * Blocks until a new connection is established on this socket or error
+ * @return new connection socket
+ * @exception SocketException thrown if attempt to accept a new connection fails
+ */
+ TCPSocket *accept() throw(SocketException);
+
+private:
+ void setListen(int queueLen) throw(SocketException);
+};
+
+/**
+ * UDP socket class
+ */
+class UDPSocket : public CommunicatingSocket {
+public:
+ /**
+ * Construct a UDP socket
+ * @exception SocketException thrown if unable to create UDP socket
+ */
+ UDPSocket() throw(SocketException);
+
+ /**
+ * Construct a UDP socket with the given local port
+ * @param localPort local port
+ * @exception SocketException thrown if unable to create UDP socket
+ */
+ UDPSocket(unsigned short localPort) throw(SocketException);
+
+ /**
+ * Construct a UDP socket with the given local port and address
+ * @param localAddress local address
+ * @param localPort local port
+ * @exception SocketException thrown if unable to create UDP socket
+ */
+ UDPSocket(const string &localAddress, unsigned short localPort)
+ throw(SocketException);
+
+ /**
+ * Unset foreign address and port
+ * @return true if disassociation is successful
+ * @exception SocketException thrown if unable to disconnect UDP socket
+ */
+ void disconnect() throw(SocketException);
+
+ /**
+ * Send the given buffer as a UDP datagram to the
+ * specified address/port
+ * @param buffer buffer to be written
+ * @param bufferLen number of bytes to write
+ * @param foreignAddress address (IP address or name) to send to
+ * @param foreignPort port number to send to
+ * @return true if send is successful
+ * @exception SocketException thrown if unable to send datagram
+ */
+ void sendTo(const void *buffer, int bufferLen, const string &foreignAddress,
+ unsigned short foreignPort) throw(SocketException);
+
+ /**
+ * Read read up to bufferLen bytes data from this socket. The given buffer
+ * is where the data will be placed
+ * @param buffer buffer to receive data
+ * @param bufferLen maximum number of bytes to receive
+ * @param sourceAddress address of datagram source
+ * @param sourcePort port of data source
+ * @return number of bytes received and -1 for error
+ * @exception SocketException thrown if unable to receive datagram
+ */
+ int recvFrom(void *buffer, int bufferLen, string &sourceAddress,
+ unsigned short &sourcePort) throw(SocketException);
+
+ /**
+ * Set the multicast TTL
+ * @param multicastTTL multicast TTL
+ * @exception SocketException thrown if unable to set TTL
+ */
+ void setMulticastTTL(unsigned char multicastTTL) throw(SocketException);
+
+ /**
+ * Join the specified multicast group
+ * @param multicastGroup multicast group address to join
+ * @exception SocketException thrown if unable to join group
+ */
+ void joinGroup(const string &multicastGroup) throw(SocketException);
+
+ /**
+ * Leave the specified multicast group
+ * @param multicastGroup multicast group address to leave
+ * @exception SocketException thrown if unable to leave group
+ */
+ void leaveGroup(const string &multicastGroup) throw(SocketException);
+
+private:
+ void setBroadcast();
+};
+
+#endif
diff --git a/anytun.cpp b/anytun.cpp
index 9884f5f..ba6c688 100644
--- a/anytun.cpp
+++ b/anytun.cpp
@@ -44,14 +44,14 @@ int main(int argc, char* argv[])
std::cout << "anytun - secure anycast tunneling protocol" << std::endl;
TunDevice* dev;
- dev = new TunDevice("tun", "192.168.200.1", "192.168.201.1");
-// dev = new TunDevice("tap", "192.168.202.1", "255.255.255.0");
+// dev = new TunDevice("tun", "192.168.200.1", "192.168.201.1");
+ dev = new TunDevice("tap", "192.168.202.1", "255.255.255.0");
// dev = new TunDevice("tun17", "192.168.200.1", "192.168.201.1");
std::cout << "dev created (opened)" << std::endl;
std::cout << "dev opened - actual name is '" << dev->getActualName() << "'" << std::endl;
std::cout << "dev type is '" << dev->getType() << "'" << std::endl;
- Buffer inBuf(1000);
+ Buffer inBuf(2000);
int len;
do
{
diff --git a/tunDevice.cpp b/tunDevice.cpp
index 84b6964..2dc7971 100644
--- a/tunDevice.cpp
+++ b/tunDevice.cpp
@@ -100,7 +100,7 @@ TunDevice::TunDevice(const char* dev_name, const char* ifcfg_lp, const char* ifc
throw std::runtime_error("can't init tun/tap device");
open_tun (dev_name, NULL, NULL, false, dev_);
- do_ifconfig(dev_, dev_->actual_name, 1500, NULL);
+ do_ifconfig(dev_, dev_->actual_name, 1000, NULL);
}
TunDevice::~TunDevice()