Compare commits
28 Commits
Author | SHA1 | Date |
---|---|---|
|
dfd75f2f67 | 7 months ago |
|
0c3b402c17 | 2 years ago |
|
9817a6b5a8 | 4 years ago |
|
a08592e3f8 | 4 years ago |
|
62b191f37d | 4 years ago |
|
120b99579f | 5 years ago |
|
a30fcb9ad0 | 5 years ago |
|
c9108c6d81 | 5 years ago |
|
7d0b48d7bf | 5 years ago |
|
dd9359c709 | 5 years ago |
|
d4b300f576 | 5 years ago |
|
1b795fdb6b | 5 years ago |
|
3b10916f8f | 5 years ago |
|
df22906ada | 5 years ago |
|
5ecd53c277 | 6 years ago |
|
49709b7915 | 6 years ago |
|
43a2e79418 | 6 years ago |
|
9888a7411a | 6 years ago |
|
eb8b60d2cf | 6 years ago |
|
a51d1c9bef | 7 years ago |
|
5f77b45d24 | 7 years ago |
|
228ff862b2 | 7 years ago |
|
37be3de810 | 7 years ago |
|
1acdca5dad | 7 years ago |
|
549f23afd8 | 7 years ago |
|
14ff60053b | 7 years ago |
|
fe87c3f425 | 7 years ago |
|
058d69b97c | 7 years ago |
@ -0,0 +1,162 @@
|
|||||||
|
fbconfig.config
|
||||||
|
*.oo
|
||||||
|
*.o
|
||||||
|
*.so.*
|
||||||
|
*.so
|
||||||
|
test-ssl
|
||||||
|
test-tcpclient
|
||||||
|
test-tcpserver
|
||||||
|
test-udp
|
||||||
|
.depend
|
||||||
|
.Makefile.rules
|
||||||
|
|
||||||
|
# ---> Eclipse
|
||||||
|
.metadata
|
||||||
|
bin/
|
||||||
|
tmp/
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*~.nib
|
||||||
|
local.properties
|
||||||
|
.settings/
|
||||||
|
.loadpath
|
||||||
|
.recommenders
|
||||||
|
|
||||||
|
# External tool builders
|
||||||
|
.externalToolBuilders/
|
||||||
|
|
||||||
|
# Locally stored "Eclipse launch configurations"
|
||||||
|
*.launch
|
||||||
|
|
||||||
|
# PyDev specific (Python IDE for Eclipse)
|
||||||
|
*.pydevproject
|
||||||
|
|
||||||
|
# CDT-specific (C/C++ Development Tooling)
|
||||||
|
.cproject
|
||||||
|
|
||||||
|
# CDT- autotools
|
||||||
|
.autotools
|
||||||
|
|
||||||
|
# Java annotation processor (APT)
|
||||||
|
.factorypath
|
||||||
|
|
||||||
|
# PDT-specific (PHP Development Tools)
|
||||||
|
.buildpath
|
||||||
|
|
||||||
|
# sbteclipse plugin
|
||||||
|
.target
|
||||||
|
|
||||||
|
# Tern plugin
|
||||||
|
.tern-project
|
||||||
|
|
||||||
|
# TeXlipse plugin
|
||||||
|
.texlipse
|
||||||
|
|
||||||
|
# STS (Spring Tool Suite)
|
||||||
|
.springBeans
|
||||||
|
|
||||||
|
# Code Recommenders
|
||||||
|
.recommenders/
|
||||||
|
|
||||||
|
# Annotation Processing
|
||||||
|
.apt_generated/
|
||||||
|
.apt_generated_test/
|
||||||
|
|
||||||
|
# Scala IDE specific (Scala & Java development for Eclipse)
|
||||||
|
.cache-main
|
||||||
|
.scala_dependencies
|
||||||
|
.worksheet
|
||||||
|
|
||||||
|
# Uncomment this line if you wish to ignore the project description file.
|
||||||
|
# Typically, this file would be tracked if it contains build/dependency configurations:
|
||||||
|
.project
|
||||||
|
|
||||||
|
# ---> C++
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
*.smod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
# ---> C
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Linker output
|
||||||
|
*.ilk
|
||||||
|
*.map
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
*.idb
|
||||||
|
*.pdb
|
||||||
|
|
||||||
|
# Kernel Module Compile Results
|
||||||
|
*.mod*
|
||||||
|
*.cmd
|
||||||
|
.tmp_versions/
|
||||||
|
modules.order
|
||||||
|
Module.symvers
|
||||||
|
Mkfile.old
|
||||||
|
dkms.conf
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
2023-11-17:
|
||||||
|
- TCP::WebGetFile timeout increased to 20000ms and added another function including an timeout parameter.
|
||||||
|
|
||||||
|
2022-02-02:
|
||||||
|
- TCP::WebGetFile downloaading from web is working fine now.
|
||||||
|
- TCP constructor is dealing better on windows now. WinSock is Hell.
|
||||||
|
|
||||||
|
2020-10-18:
|
||||||
|
- needed to disable ipv6 on windows for the moment, as long as i can't
|
||||||
|
get both ipv4 and ipv6 to work at the same time.
|
||||||
|
- fixed getpeername was not supported on accept connections
|
||||||
|
- fixed windows support with TCP sockets. Needed to call closesocket on windows.
|
||||||
|
- added support for windows. Everything should work but UNIX sockets.
|
||||||
|
|
||||||
|
2020-10-15:
|
||||||
|
- added: TCP::isListen function
|
||||||
|
|
||||||
|
2019-12-29:
|
||||||
|
- added: UDP reads can be set to non blocked mode.
|
||||||
|
|
||||||
|
2019-07-21:
|
||||||
|
- fixed: compile will work with older versions of SSL.
|
||||||
|
|
||||||
|
2019-05-05:
|
||||||
|
- added SSLSocket support. SSL.Connect (TCP.GetSocket())
|
||||||
|
it supports as well as non blocking connections with a defined timeout.
|
||||||
|
|
||||||
|
2019-03-04:
|
||||||
|
- added: TCP connections have set up a timeout of 2 seconds.
|
||||||
|
- fixed: TCP connect set up the sock struct too fast so threaded applications had some
|
||||||
|
problem if the connect went into a time out.
|
||||||
|
|
||||||
|
2019-02-21:
|
||||||
|
- fixed: TCP::Accept needed to set up the lenght of the sockaddr structure
|
||||||
|
|
||||||
|
2019-02-03:
|
||||||
|
- fixed: if connection could not established we need to clear sock to -1
|
||||||
|
- fixed: setsockopt SO_REUSE was not right option was not setup properly
|
||||||
|
|
||||||
|
2019-01-30:
|
||||||
|
- Adding unix socket to the possible connections
|
||||||
|
|
||||||
|
2019-01-26:
|
||||||
|
- TCP::Write - added MSG_NOSIGNAL to send, in case something gets wrong the application would stop working
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
PREFIX = /usr/local
|
||||||
|
ETCPREFIX = /etc
|
||||||
|
|
||||||
|
LINUXVERSION = 1
|
||||||
|
|
||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -ggdb -fPIC -pg -Wno-write-strings -I./ -std=c++11 -DBUILD_LINUX=1
|
||||||
|
LDFLAGS = -lm -pg -lssl -lcrypto
|
||||||
|
|
||||||
|
TARGET = lib$(OBJLIB_NAME).so.$(VERSION)
|
||||||
|
|
||||||
|
DISTNAME = lib$(OBJLIB_NAME)-$(VERSION)
|
||||||
|
DEPENDFILE = .depend
|
||||||
|
|
||||||
|
LINKPARAMS = -Wl,-soname,lib$(OBJLIB_NAME).so
|
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
VERSION = 0.1
|
||||||
|
PREFIX = /usr
|
||||||
|
ETCPREFIX = /etc
|
||||||
|
WINVERSION = 1
|
||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -ggdb -fPIC -Wno-write-strings -I./ -std=c++11 -DBUILD_WINDOWS=1
|
||||||
|
LDFLAGS = -lm -lssl -lcrypto -lwsock32 -lws2_32
|
||||||
|
TARGET = $(OBJLIB_NAME).dll
|
||||||
|
|
||||||
|
DISTNAME = lib$(OBJLIB_NAME)-$(VERSION)
|
||||||
|
DEPENDFILE = .depend
|
||||||
|
|
||||||
|
LINKPARAMS = -Wl,--out-implib,libUDPTCPNetwork.a
|
@ -0,0 +1,108 @@
|
|||||||
|
# .SILENT:
|
||||||
|
#
|
||||||
|
# to build the windows version please install MSYS2
|
||||||
|
#
|
||||||
|
# this file should not been used anymore use make configwindows; make ; make install instead
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VERSION=0.1
|
||||||
|
PREFIX=/usr
|
||||||
|
ETCPREFIX=/etc
|
||||||
|
WINVERSION = 1
|
||||||
|
CXX=g++
|
||||||
|
CXXFLAGS= -ggdb -fPIC -Wno-write-strings -I./ -std=c++11 -DBUILD_WINDOWS
|
||||||
|
LDFLAGS= -lm -lssl -lcrypto -lwsock32 -lws2_32
|
||||||
|
|
||||||
|
DEFAULT_TCPPORT=6131
|
||||||
|
DEFAULT_UDPPORT=6131
|
||||||
|
DEFAULT_SERVER=localhost
|
||||||
|
|
||||||
|
OBJLIB=network.o udp.o tcp.o unix.o ssl.o
|
||||||
|
INCLIB=config.h UDPTCPNetwork.h
|
||||||
|
OBJLIB_NAME=UDPTCPNetwork
|
||||||
|
TARGET=UDPTCPNetwork.dll
|
||||||
|
|
||||||
|
DISTNAME=libUDPTCPNetwork-$(VERSION)
|
||||||
|
DEPENDFILE=.depend
|
||||||
|
|
||||||
|
all: dep $(TARGET) test-udp test-tcp test-ssl
|
||||||
|
|
||||||
|
test-tcp: $(TARGET) test-tcp.o config.h
|
||||||
|
$(CXX) test-tcp.o -o $@ -lUDPTCPNetwork -L./ -I./ $(LDFLAGS)
|
||||||
|
|
||||||
|
test-ssl: $(TARGET) test-ssl.o config.h
|
||||||
|
$(CXX) test-ssl.o -o $@ -lUDPTCPNetwork -L./ -I./ $(LDFLAGS)
|
||||||
|
|
||||||
|
test-udp: $(TARGET) test-udp.o config.h
|
||||||
|
$(CXX) test-udp.o -o $@ -lUDPTCPNetwork -L./ -I./ $(LDFLAGS)
|
||||||
|
|
||||||
|
keygen:
|
||||||
|
# openssl req -nodes -new -newkey rsa:2048 -sha256 -out csr.pem -keyout privkey.pem
|
||||||
|
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privkey.pem -out cert.pem
|
||||||
|
|
||||||
|
install: $(TARGET)
|
||||||
|
cp -f $(TARGET) $(PREFIX)/lib/
|
||||||
|
cp -f UDPTCPNetwork.h $(PREFIX)/include/
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -f $(PREFIX)/lib/$(TARGET)
|
||||||
|
rm -f $(PREFIX)/lib/lib$(OBJLIB_NAME).so
|
||||||
|
rm -f $(PREFIX)/include/UDPTCPNetwork.h
|
||||||
|
|
||||||
|
rebuild: clean all
|
||||||
|
|
||||||
|
$(TARGET): $(OBJLIB) $(INCLIB)
|
||||||
|
$(CXX) -shared $(LINKPARAMS) -o $(TARGET) $^ $(LDFLAGS)
|
||||||
|
ln -sf $(TARGET) lib$(OBJLIB_NAME).so
|
||||||
|
ar rcs lib$(OBJLIB_NAME).a $(OBJLIB)
|
||||||
|
|
||||||
|
dep:
|
||||||
|
$(CXX) -MM `ls *.cc` $(CXXFLAGS) > $(DEPENDFILE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm test-tcp -rf
|
||||||
|
rm test-udp -rf
|
||||||
|
rm test-ssl -rf
|
||||||
|
rm -rf gmon.out
|
||||||
|
rm *.s -rf
|
||||||
|
rm *.a -rf
|
||||||
|
rm -rf *.dll
|
||||||
|
rm *.o -rf
|
||||||
|
rm *.oo -rf
|
||||||
|
rm *~ -rf
|
||||||
|
rm -rf config.h
|
||||||
|
rm -rf .depend
|
||||||
|
rm -rf *.so
|
||||||
|
rm -rf *.a
|
||||||
|
rm -rf *.so.*
|
||||||
|
rm -rf *.pem -rf
|
||||||
|
|
||||||
|
|
||||||
|
cleanall: clean
|
||||||
|
|
||||||
|
source: cleanall
|
||||||
|
|
||||||
|
config:
|
||||||
|
echo "#ifndef _CONFIG_H_" > config.h
|
||||||
|
echo "#define _CONFIG_H_" >> config.h
|
||||||
|
echo "" >> config.h
|
||||||
|
echo "#define UDPTCPNETWORK_VERSION \"$(VERSION)\"" >> config.h
|
||||||
|
echo "" >> config.h
|
||||||
|
echo "#define PREFIX \"$(PREFIX)\"" >> config.h
|
||||||
|
echo "#define ETCPREFIX \"$(ETCPREFIX)\"" >> config.h
|
||||||
|
echo "" >> config.h
|
||||||
|
echo "#endif" >> config.h
|
||||||
|
|
||||||
|
dist: clean
|
||||||
|
mkdir -p $(DISTNAME)
|
||||||
|
cp -rf Makefile $(DISTNAME)
|
||||||
|
cp -rf *.h $(DISTNAME)
|
||||||
|
cp -rf *.cc $(DISTNAME)
|
||||||
|
tar cvzf $(DISTNAME).tgz --exclude=*/CVS/* --exclude=*/CVS/ $(DISTNAME)
|
||||||
|
rm -rf $(DISTNAME)
|
||||||
|
|
||||||
|
-include $(DEPENDFILE)
|
||||||
|
|
@ -0,0 +1,307 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h> /* close() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h> /* memset() */
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
#include "UDPTCPNetwork.h"
|
||||||
|
|
||||||
|
static int ssl_init = 0;
|
||||||
|
|
||||||
|
SSLSocket::SSLSocket() {
|
||||||
|
readcnt = 0;
|
||||||
|
writecnt = 0;
|
||||||
|
certfile = "";
|
||||||
|
keyfile = "";
|
||||||
|
sslerror = SSL_ERROR_NONE;
|
||||||
|
timeout = 0;
|
||||||
|
ctx = NULL;
|
||||||
|
ssl = NULL;
|
||||||
|
if (ssl_init == 0) {
|
||||||
|
ssl_init = 1;
|
||||||
|
SSL_library_init();
|
||||||
|
OpenSSL_add_all_algorithms();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SSLSocket::~SSLSocket() {
|
||||||
|
if (ctx) SSL_CTX_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
if (ssl) SSL_free(ssl);
|
||||||
|
ssl = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int SSLSocket::NewServerCTX() {
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat (certfile.c_str(), &st)) return 0;
|
||||||
|
if (stat (keyfile.c_str(), &st)) return 0;
|
||||||
|
|
||||||
|
if (ctx) SSL_CTX_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
#ifdef SSLv23_method
|
||||||
|
ctx = SSL_CTX_new(TLS_server_method());
|
||||||
|
#else
|
||||||
|
ctx = SSL_CTX_new(TLSv1_2_server_method());
|
||||||
|
#endif
|
||||||
|
if (SSL_CTX_use_certificate_file(ctx, certfile.c_str(), SSL_FILETYPE_PEM) <= 0 ) {
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
if (ctx) SSL_CTX_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
errno = EPROTO;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( SSL_CTX_use_PrivateKey_file(ctx, keyfile.c_str(), SSL_FILETYPE_PEM) <= 0 ) {
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
if (ctx) SSL_CTX_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
errno = EPROTO;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SSL_CTX_check_private_key(ctx)) {
|
||||||
|
if (ctx) SSL_CTX_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
errno = EPROTO;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int SSLSocket::NewClientCTX() {
|
||||||
|
if (ctx) SSL_CTX_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
#ifdef SSLv23_method
|
||||||
|
ctx = SSL_CTX_new(TLS_client_method());
|
||||||
|
#else
|
||||||
|
ctx = SSL_CTX_new(TLSv1_2_client_method());
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int SSLSocket::SetCertificat(string certf, string keyf) {
|
||||||
|
certfile = certf;
|
||||||
|
keyfile = keyf;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int SSLSocket::Connect (int sockfd, int block_timeout) {
|
||||||
|
int flags, res;
|
||||||
|
|
||||||
|
TimeoutReset();
|
||||||
|
sslerror = SSL_ERROR_NONE;
|
||||||
|
NewClientCTX();
|
||||||
|
timeout = block_timeout;
|
||||||
|
|
||||||
|
if (sockfd > 0 && block_timeout > 0) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
|
||||||
|
u_long mode = 1;
|
||||||
|
ioctlsocket(sockfd, FIONBIO, &mode);
|
||||||
|
#else
|
||||||
|
flags = fcntl(sockfd, F_GETFL, 0);
|
||||||
|
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl = SSL_new(ctx);
|
||||||
|
SSL_set_fd (ssl, sockfd);
|
||||||
|
|
||||||
|
do {
|
||||||
|
res = SSL_connect(ssl);
|
||||||
|
if (res == -1) sslerror = SSL_get_error(ssl, -1);
|
||||||
|
} while (res == -1 && TimeoutTime() < timeout &&
|
||||||
|
(sslerror == SSL_ERROR_WANT_READ || sslerror == SSL_ERROR_WANT_WRITE));
|
||||||
|
|
||||||
|
if (res == -1) return 0;
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int SSLSocket::Accept (int sockfd, int block_timeout) {
|
||||||
|
int flags, res;
|
||||||
|
|
||||||
|
TimeoutReset();
|
||||||
|
sslerror = SSL_ERROR_NONE;
|
||||||
|
timeout = block_timeout;
|
||||||
|
NewServerCTX();
|
||||||
|
|
||||||
|
if (sockfd > 0 && block_timeout > 0) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
|
||||||
|
u_long mode = 1;
|
||||||
|
ioctlsocket(sockfd, FIONBIO, &mode);
|
||||||
|
#else
|
||||||
|
flags = fcntl(sockfd, F_GETFL, 0);
|
||||||
|
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl = SSL_new(ctx);
|
||||||
|
SSL_set_fd (ssl, sockfd);
|
||||||
|
do {
|
||||||
|
res = SSL_accept(ssl);
|
||||||
|
if (res == -1) sslerror = SSL_get_error(ssl, -1);
|
||||||
|
} while (res == -1 && TimeoutTime() < timeout &&
|
||||||
|
(sslerror == SSL_ERROR_WANT_READ || sslerror == SSL_ERROR_WANT_WRITE));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const string SSLSocket::GetSSLErrorText(int err) {
|
||||||
|
string s;
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case SSL_ERROR_NONE:
|
||||||
|
s = "SSL_ERROR_NONE";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSL_ERROR_SSL:
|
||||||
|
s = "SSL_ERROR_SSL";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
s = "SSL_ERROR_WANT_READ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
s = "SSL_ERROR_WANT_WRITE";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
s = "SSL_ERROR_SYSCALL";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSL_ERROR_WANT_CONNECT:
|
||||||
|
s = "SSL_ERROR_WANT_CONNECT";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
|
s = "SSL_ERROR_ZERO_RETURN";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSL_ERROR_WANT_ACCEPT:
|
||||||
|
s = "SSL_ERROR_WANT_ACCEPT";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s = "SSL_ERROR unknown " + to_string(err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// close ssl and return socket.
|
||||||
|
int SSLSocket::Close () {
|
||||||
|
int sock = 0;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
if (ssl) {
|
||||||
|
sock = SSL_get_fd(ssl);
|
||||||
|
SSL_free(ssl);
|
||||||
|
ssl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx) {
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock > 0 && timeout > 0) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
|
||||||
|
u_long mode = 0;
|
||||||
|
ioctlsocket(sock, FIONBIO, &mode);
|
||||||
|
#else
|
||||||
|
flags = fcntl(sock, F_GETFL, 0);
|
||||||
|
fcntl(sock, F_SETFL, flags & ~(O_NONBLOCK));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
long int SSLSocket::Read (char *buffer, long int len) {
|
||||||
|
int ret;
|
||||||
|
sslerror = SSL_ERROR_NONE;
|
||||||
|
|
||||||
|
TimeoutReset();
|
||||||
|
|
||||||
|
if (!ssl) {
|
||||||
|
errno = EPROTO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = SSL_read(ssl, buffer, len);
|
||||||
|
if (ret == -1) sslerror = SSL_get_error(ssl, -1);
|
||||||
|
} while (ret == -1 && TimeoutTime() < timeout &&
|
||||||
|
(sslerror == SSL_ERROR_WANT_READ || sslerror == SSL_ERROR_WANT_WRITE));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
long int SSLSocket::Write (char *buffer, long int len) {
|
||||||
|
int ret;
|
||||||
|
sslerror = SSL_ERROR_NONE;
|
||||||
|
TimeoutReset();
|
||||||
|
|
||||||
|
if (!ssl) {
|
||||||
|
errno = EPROTO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = SSL_write(ssl, buffer, len);
|
||||||
|
if (ret == -1) sslerror = SSL_get_error(ssl, -1);
|
||||||
|
} while (ret == -1 && TimeoutTime() < timeout &&
|
||||||
|
(sslerror == SSL_ERROR_WANT_READ || sslerror == SSL_ERROR_WANT_WRITE));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reset Timeout Timer
|
||||||
|
void SSLSocket::TimeoutReset() {
|
||||||
|
gettimeofday (&timeout_start, NULL);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return time which has past since reset in ms.
|
||||||
|
int SSLSocket::TimeoutTime() {
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday (&tv, NULL);
|
||||||
|
|
||||||
|
return ((tv.tv_sec-timeout_start.tv_sec) * 1000) +
|
||||||
|
((tv.tv_usec-timeout_start.tv_usec) / 1000);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,157 @@
|
|||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "UDPTCPNetwork.h"
|
||||||
|
|
||||||
|
#define DEFAULT_PORT 12345
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
|
||||||
|
#else
|
||||||
|
|
||||||
|
void server () {
|
||||||
|
TCP tcpserver;
|
||||||
|
TCP *connection;
|
||||||
|
SSLSocket ssl;
|
||||||
|
int i, timeout;
|
||||||
|
pid_t pid;
|
||||||
|
time_t time_start = time (NULL);
|
||||||
|
time_t time_now = time (NULL);
|
||||||
|
char buffer[NET_BUFFERSIZE];
|
||||||
|
|
||||||
|
//
|
||||||
|
// start the server
|
||||||
|
if (tcpserver.Listen(DEFAULT_PORT) != 1) {
|
||||||
|
printf ("cloud not start the tcp server\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// init SSL
|
||||||
|
if (ssl.SetCertificat("cert.pem", "privkey.pem") != 1) {
|
||||||
|
printf ("SetCertificat error:%s\n", strerror(errno));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// check for connections
|
||||||
|
for (;time_now - time_start < 10; time_now = time(NULL)) {
|
||||||
|
connection = tcpserver.Accept();
|
||||||
|
if (connection != NULL) {
|
||||||
|
//
|
||||||
|
// someone connected - create new process
|
||||||
|
// take care of parallel processing (parent is always the server)
|
||||||
|
//
|
||||||
|
printf (" server: got a connection forking new process\n");
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
//
|
||||||
|
// child process - always close server since it will handeled
|
||||||
|
// by the parent process. Make sure the client exits and never
|
||||||
|
// returns.
|
||||||
|
|
||||||
|
tcpserver.Close();
|
||||||
|
if (ssl.Accept(connection->GetSocket(), 0) != 1) {
|
||||||
|
printf ("could not establish SSL connection:%s\n", strerror(errno));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
i = ssl.Read(buffer, NET_BUFFERSIZE);
|
||||||
|
if (i > 0) {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
printf (" server: got: '%s'\n", buffer);
|
||||||
|
for (c = 0; c < i; c++) buffer[c] = toupper(buffer[c]);
|
||||||
|
ssl.Write(buffer, i);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// just delete the class object, it will close the client connection
|
||||||
|
ssl.Close();
|
||||||
|
delete (connection);
|
||||||
|
|
||||||
|
//
|
||||||
|
// exit child process
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//
|
||||||
|
// parent process - just close the client connection
|
||||||
|
// it will be handeled by the child process.
|
||||||
|
delete (connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usleep (25000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void client () {
|
||||||
|
TCP tcpclient;
|
||||||
|
SSLSocket ssl;
|
||||||
|
char buffer[NET_BUFFERSIZE];
|
||||||
|
int i, res;
|
||||||
|
|
||||||
|
sleep (1); // wait one second to start the server
|
||||||
|
|
||||||
|
//
|
||||||
|
// connect to the server
|
||||||
|
if (tcpclient.Connect ("localhost", DEFAULT_PORT) != 1) {
|
||||||
|
printf ("cloud not connect to server\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ssl.Connect(tcpclient.GetSocket(), 100);
|
||||||
|
if (res == -1) {
|
||||||
|
printf ("could not establish SSL connection:errno:%s sslerror:%s\n", strerror(errno), ssl.GetSSLErrorText(ssl.sslerror).c_str());
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// send some data
|
||||||
|
snprintf (buffer, NET_BUFFERSIZE, "nur ein kleiner Test.");
|
||||||
|
printf ("client:send '%s' to the server.\n", buffer);
|
||||||
|
|
||||||
|
if (ssl.Write(buffer, strlen (buffer)) != strlen (buffer)) {
|
||||||
|
printf ("could not send all data. errno:%s sslerror:%s\n", strerror(errno), ssl.GetSSLErrorText(ssl.sslerror).c_str());
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// read some data (wait maximum 10x1000ms)
|
||||||
|
for (i = 10; i > 0; i--)
|
||||||
|
if (ssl.Read(buffer, NET_BUFFERSIZE) > 0) {
|
||||||
|
printf ("client:got '%s' from server.\n", buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// close connection
|
||||||
|
ssl.Close();
|
||||||
|
tcpclient.Close();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main (int argc, char **argv) {
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
|
||||||
|
#else
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) { // child process
|
||||||
|
printf ("start client\n");
|
||||||
|
client();
|
||||||
|
printf ("start client\n");
|
||||||
|
client();
|
||||||
|
printf ("start client\n");
|
||||||
|
client();
|
||||||
|
printf ("start client\n");
|
||||||
|
client();
|
||||||
|
}
|
||||||
|
else { // parent process
|
||||||
|
server();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,69 @@
|
|||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "UDPTCPNetwork.h"
|
||||||
|
|
||||||
|
#define DEFAULT_PORT 12345
|
||||||
|
|
||||||
|
int main (int argc, char **argv) {
|
||||||
|
TCP tcpclient;
|
||||||
|
char buffer[NET_BUFFERSIZE];
|
||||||
|
int i;
|
||||||
|
int loop;
|
||||||
|
|
||||||
|
#ifdef BUILD_WINDOWS
|
||||||
|
char iobuffer[16];
|
||||||
|
setvbuf (stdout, iobuffer, _IONBF, 16);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// connect to the server
|
||||||
|
if (argc == 2) {
|
||||||
|
if (tcpclient.Connect(argv[1], DEFAULT_PORT) != 1) {
|
||||||
|
printf ("connect to: %s:%d\n",argv[1], DEFAULT_PORT);
|
||||||
|
printf ("cloud not connect to server\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (argc == 3) {
|
||||||
|
printf ("connect to: %s:%d\n",argv[1], atoi(argv[2]));
|
||||||
|
if (tcpclient.Connect(argv[1], argv[2]) != 1) {
|
||||||
|
printf ("cloud not connect to server\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf ("\nplease use the ollowing commands:\n\n");
|
||||||
|
printf (" test-tcpclient destination\n");
|
||||||
|
printf (" test-tcpclient destination port\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (loop = 0; loop < 5; loop++) {
|
||||||
|
//
|
||||||
|
// send some data
|
||||||
|
snprintf (buffer, NET_BUFFERSIZE, "nur ein kleiner Test.");
|
||||||
|
printf ("client:send '%s' to the server.\n", buffer);
|
||||||
|
if (tcpclient.Write(buffer, strlen (buffer)) != strlen (buffer)) {
|
||||||
|
printf ("could not send all data.\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// read some data (wait maximum 10x1000ms)
|
||||||
|
for (i = 10; i > 0; i--)
|
||||||
|
if (tcpclient.ReadTimeout(buffer, NET_BUFFERSIZE, 1000) > 0) {
|
||||||
|
printf ("client:got '%s' from server.\n", buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep (1);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// close connection
|
||||||
|
tcpclient.Close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "UDPTCPNetwork.h"
|
||||||
|
|
||||||
|
#define DEFAULT_PORT 12345
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
TCP tcpserver;
|
||||||
|
TCP *connection = NULL;
|
||||||
|
int i, timeout;
|
||||||
|
pid_t pid;
|
||||||
|
time_t time_start = time (NULL);
|
||||||
|
time_t time_now = time (NULL);
|
||||||
|
char buffer[NET_BUFFERSIZE];
|
||||||
|
|
||||||
|
#ifdef BUILD_WINDOWS
|
||||||
|
char iobuffer[16];
|
||||||
|
setvbuf (stdout, iobuffer, _IONBF, 16);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// start the server
|
||||||
|
if (tcpserver.Listen(DEFAULT_PORT) != 1) {
|
||||||
|
printf ("cloud not start the tcp server\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("server started\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// check for connections
|
||||||
|
while(1) {
|
||||||
|
if (connection == NULL) {
|
||||||
|
connection = tcpserver.Accept();
|
||||||
|
printf ("accept connection? %p\n", connection);
|
||||||
|
if (connection != NULL)
|
||||||
|
printf (" server: got a new connection from:%s\n", connection->GetRemoteAddr().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connection != NULL) {
|
||||||
|
memset (buffer, 0x0, NET_BUFFERSIZE);
|
||||||
|
i = connection->ReadTimeout(buffer, NET_BUFFERSIZE, 100);
|
||||||
|
if (i > 0) {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
printf (" server: (child) got: '%s'\n", buffer);
|
||||||
|
for (c = 0; c < i; c++) buffer[c] = toupper(buffer[c]);
|
||||||
|
connection->Write(buffer, i);
|
||||||
|
}
|
||||||
|
else if (i < 0) {
|
||||||
|
delete connection;
|
||||||
|
connection = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usleep (25000);
|
||||||
|
}
|
||||||
|
tcpserver.Close();
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h> /* close() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h> /* memset() */
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "UDPTCPNetwork.h"
|
||||||
|
|
||||||
|
// for now no support on windows
|
||||||
|
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
|
||||||
|
#warning UNIX socket are not supported on windows.
|
||||||
|
#else
|
||||||
|
|
||||||
|
UNIX::~UNIX() {
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
UNIX::UNIX() {
|
||||||
|
sock = 0;
|
||||||
|
fname = "";
|
||||||
|
writecnt = 0;
|
||||||
|
readcnt = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UNIX::UNIX (int fd, string filename) {
|
||||||
|
sock = fd;
|
||||||
|
fname = filename;
|
||||||
|
writecnt = 0;
|
||||||
|
readcnt = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int UNIX::Listen(string filename) {
|
||||||
|
char buffer[NET_BUFFERSIZE];
|
||||||
|
int err, i;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
if (sock > 0) Close();
|
||||||
|
unlink(filename.c_str());
|
||||||
|
|
||||||
|
memset (&addr,0, sizeof addr);
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strncpy (addr.sun_path, filename.c_str(), sizeof (addr.sun_path));
|
||||||
|
|
||||||
|
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||||
|
sock = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
|
||||||
|
close (sock);
|
||||||
|
sock = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(sock, 8) == -1) {
|
||||||
|
close (sock);
|
||||||
|
sock = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UNIX* UNIX::Accept() {
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
int retval, newsock, err, i;
|
||||||
|
char host[NET_BUFFERSIZE];
|
||||||
|
char port[NET_BUFFERSIZE];
|
||||||
|
UNIX *named = NULL;
|
||||||
|
struct sockaddr_storage cli_addr;
|
||||||
|
unsigned int cli_len;
|
||||||
|
|
||||||
|
if (sock <= 0) return NULL;
|
||||||
|
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(sock, &rfds);
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 1000;
|
||||||
|
|
||||||
|
retval = select (sock+1, &rfds, NULL, NULL, &tv);
|
||||||
|
if (retval == -1 && errno == EINTR) {
|
||||||
|
retval = 0;
|
||||||
|
}
|
||||||
|
else if (retval == -1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (retval) {
|
||||||
|
newsock = accept (sock, NULL, NULL);
|
||||||
|
if (newsock < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
named = new UNIX(newsock, fname);
|
||||||
|
return named;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int UNIX::Connect(string filename) {
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
if (sock > 0) Close();
|
||||||
|
|
||||||
|
memset (&addr,0, sizeof addr);
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strncpy (addr.sun_path, filename.c_str(), sizeof (addr.sun_path));
|
||||||
|
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (connect(sock,(struct sockaddr *) &addr, sizeof (addr)) == -1) {
|
||||||
|
close (sock);
|
||||||
|
sock = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
long int UNIX::Read(char *buffer, long int len) {
|
||||||
|
long int len_ = len;
|
||||||
|
|
||||||
|
if (sock <= 0) return -2;
|
||||||
|
len_ = read (sock, (void*)buffer, len);
|
||||||
|
|
||||||
|
if (len_ < 0 && errno == EAGAIN) len_ = 0;
|
||||||
|
else if (len_ < 0 && errno != EAGAIN) {
|
||||||
|
len_ = -2;
|
||||||
|
}
|
||||||
|
else if (len_ == 0) len_ = -1;
|
||||||
|
if (len_ < 0) Close();
|
||||||
|
|
||||||
|
readcnt += len_;
|
||||||
|
|
||||||
|
return len_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
long int UNIX::ReadTimeout(char *buffer, long int len, int timeout) {
|
||||||
|
int data = IsData (timeout);
|
||||||
|
|
||||||
|
if (data > 0) return Read (buffer, len);
|
||||||
|
else if (data < 0) return -1;
|
||||||
|
else return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// write data, generate no signal if some error occures
|
||||||
|
long int UNIX::Write(char *buffer, long int len) {
|
||||||
|
int i;
|
||||||
|
int to = NET_MAX_RETRY;
|
||||||
|
|
||||||
|
if (sock <= 0) return -1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
i = send (sock, buffer, len, MSG_NOSIGNAL);
|
||||||
|
} while (i == -1 && (to--) > 0 && errno == EINTR);
|
||||||
|
|
||||||
|
if (i < 0) Close ();
|
||||||
|
writecnt += i;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void UNIX::Close() {
|
||||||
|
if (sock > 0) close (sock);
|
||||||
|
sock = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int UNIX::IsConnected() {
|
||||||
|
return (sock > 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int UNIX::IsData(int timeout) {
|
||||||
|
fd_set sockset;
|
||||||
|
struct timeval tval;
|
||||||
|
|
||||||
|
if (sock <= 0) return -1;
|
||||||
|
|
||||||
|
FD_ZERO (&sockset);
|
||||||
|
FD_SET (sock, &sockset);
|
||||||
|
tval.tv_sec = timeout / 1000;
|
||||||
|
tval.tv_usec = (timeout % 1000);
|
||||||
|
if ((select (sock + 1, &sockset, NULL, NULL, &tval)) != -1) {
|
||||||
|
if (FD_ISSET (sock, &sockset)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (errno == EBADF) sock = -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in new issue