Skip to content

Commit

Permalink
Adapted socket module to macos/POSIX
Browse files Browse the repository at this point in the history
  • Loading branch information
kfprimm committed Nov 28, 2023
1 parent 270a17a commit 4848ddb
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 67 deletions.
2 changes: 1 addition & 1 deletion src/modules/bb/sockets/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
IF(BB_DESKTOP)
IF(NOT BB_EMSCRIPTEN)
bb_start_module(sockets)
set(DEPENDS_ON bb.stream)
set(SOURCES sockets.cpp sockets.h)
Expand Down
136 changes: 71 additions & 65 deletions src/modules/bb/sockets/sockets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,46 @@
#include <sys/types.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <poll.h>

typedef int SOCKET;
typedef hostent HOSTENT;
#define ioctlsocket(fd,flags,ptr) ioctl(fd,flags,ptr)
#define closesocket(fd) close(fd)
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
#else
typedef int socklen_t;
#endif

#ifndef FIXME
#ifdef WIN32
#include <windows.h>
#endif

#ifdef WIN32
#define S_ADDR( a ) a.S_un.S_addr
#else
#define S_ADDR( a ) a.s_addr
#endif

static bool socks_ok=0;
#ifndef FIXME
#ifdef WIN32
static WSADATA wsadata;
#endif
static int recv_timeout;
static int read_timeout;
static int accept_timeout;

static void close( SOCKET sock,int e ){
#ifndef FIXME
if( e<0 ){
int opt=1;
#ifndef FIXME
setsockopt( sock,SOL_SOCKET,SO_DONTLINGER,(char*)&opt,sizeof(opt) );
#endif
}
closesocket( sock );
#endif
}

class UDPStream;
Expand Down Expand Up @@ -112,7 +125,6 @@ int UDPStream::eof(){

//fill buffer, return sender
int UDPStream::recv(){
#ifndef FIXME
if( e ) return 0;
int tout;
if( recv_timeout ) tout=bbMilliSecs()+recv_timeout;
Expand All @@ -122,70 +134,59 @@ int UDPStream::recv(){
dt=tout-bbMilliSecs();
if( dt<0 ) dt=0;
}
#ifdef WIN32
fd_set fd={ 1,sock };
timeval tv={ dt/1000,(dt%1000)*1000 };
int n=::select( 0,&fd,0,0,&tv );
#else
pollfd fd={ sock,POLLIN|POLLPRI,0 };
int n=poll( &fd,1,recv_timeout );
if( !(fd.revents&POLLIN) ) return 0;
#endif
if( !n ) return 0;
if( n!=1 ){ e=-1;return 0; }
#ifdef WIN32
unsigned long sz=-1;
#else
int sz=-1;
#endif
if( ioctlsocket( sock,FIONREAD,&sz ) ){ e=-1;return 0; }
in_buf.resize( sz );in_get=0;
int len=sizeof(in_addr);
socklen_t len=sizeof(in_addr);
n=::recvfrom( sock,&in_buf[0],sz,0,(sockaddr*)&in_addr,&len );
if( n==SOCKET_ERROR ) continue; //{ e=-1;return 0; }
in_buf.resize( n );
return getMsgIP();
}
#endif
return 0;
}

//send, empty buffer
int UDPStream::send( int ip,int port ){
#ifdef FIXME
return 0;
#else
if( e ) return 0;
int sz=out_buf.size();
out_addr.sin_addr.S_un.S_addr=htonl( ip );
S_ADDR(out_addr.sin_addr)=htonl( ip );
out_addr.sin_port=htons( port ? port : addr.sin_port );
int n=::sendto( sock,&out_buf[0],sz,0,(sockaddr*)&out_addr,sizeof(out_addr) );
if( n!=sz ) return e=-1;
out_buf.clear();
return sz;
#endif
}

int UDPStream::getIP(){
#ifdef FIXME
return 0;
#else
return ntohl( addr.sin_addr.S_un.S_addr );
#endif
return ntohl( S_ADDR( addr.sin_addr ) );
}

int UDPStream::getPort(){
#ifdef FIXME
return 0;
#else
return ntohs( addr.sin_port );
#endif
}

int UDPStream::getMsgIP(){
#ifdef FIXME
return 0;
#else
return ntohl( in_addr.sin_addr.S_un.S_addr );
#endif
return ntohl( S_ADDR( in_addr.sin_addr ) );
}

int UDPStream::getMsgPort(){
#ifdef FIXME
return 0;
#else
return ntohs( in_addr.sin_port );
#endif
}

class TCPStream : public BBStream{
Expand Down Expand Up @@ -223,29 +224,22 @@ class TCPServer{
};

TCPStream::TCPStream( SOCKET s,TCPServer *t ):sock(s),server(t),e(0){
#ifndef FIXME
sockaddr_in addr;
int len=sizeof(addr);
socklen_t len=sizeof(addr);
if( getpeername( s,(sockaddr*)&addr,&len ) ){
ip=port=0;
return;
}
ip=ntohl(addr.sin_addr.S_un.S_addr);
ip=ntohl( S_ADDR(addr.sin_addr ) );
port=ntohs(addr.sin_port);
#endif
}

TCPStream::~TCPStream(){
if( server ) server->remove( this );
#ifndef FIXME
close( sock,e );
#endif
}

int TCPStream::read( char *buff,int size ){
#ifdef FIXME
return 0;
#else
if( e ) return 0;
char *b=buff,*l=buff+size;
int tout;
Expand All @@ -256,39 +250,40 @@ int TCPStream::read( char *buff,int size ){
dt=tout-bbMilliSecs();
if( dt<0 ) dt=0;
}
fd_set fd={ 1,sock };
timeval tv={ dt/1000,(dt%1000)*1000 };
#ifdef WIN32
fd_set fd={ 1,sock };
int n=::select( 0,&fd,0,0,&tv );
if( n!=1 ){ e=-1;break; }
#else
pollfd fd={ sock,POLLIN|POLLPRI,0 };
int n=poll( &fd,1,read_timeout );
if( !(fd.revents&POLLIN) ){ e=-1;break; }
#endif
n=::recv( sock,b,l-b,0 );
if( n==0 ){ e=1;break; }
if( n==SOCKET_ERROR ){ e=-1;break; }
b+=n;
}
return b-buff;
#endif
}

int TCPStream::write( const char *buff,int size ){
#ifdef FIXME
return 0;
#else
if( e ) return 0;
int n=::send( sock,buff,size,0 );
if( n==SOCKET_ERROR ){ e=-1;return 0; }
return n;
#endif
}

int TCPStream::avail(){
#ifdef FIXME
return 0;
#ifdef WIN32
unsigned long t=-1;
#else
unsigned long t;
int t=-1;
#endif
int n=::ioctlsocket( sock,FIONREAD,&t );
if( n==SOCKET_ERROR ){ e=-1;return 0; }
return t;
#endif
}

int TCPStream::eof(){
Expand All @@ -315,26 +310,24 @@ TCPServer::TCPServer( SOCKET s ):sock(s),e(0){
}

TCPServer::~TCPServer(){
while( accepted_set.size() ) delete *accepted_set.begin();
while( accepted_set.size() ) bbCloseTCPStream( *accepted_set.begin() );
close( sock,e );
}

TCPStream *TCPServer::accept(){
#ifdef FIXME
return 0;
#else
if( e ) return 0;
#ifdef WIN32
fd_set fd={ 1,sock };
timeval tv={ accept_timeout/1000,(accept_timeout%1000)*1000 };
int n=::select( 0,&fd,0,0,&tv );
if( n==0 ) return 0;
if( n!=1 ){ e=-1;return 0; }
#endif
SOCKET t=::accept( sock,0,0 );
if( t==INVALID_SOCKET ){ e=-1;return 0; }
TCPStream *s=d_new TCPStream( t,this );
accepted_set.insert( s );
return s;
#endif
}

void TCPServer::remove( TCPStream *s ){
Expand Down Expand Up @@ -362,6 +355,9 @@ static inline void debugTCPServer( TCPServer *p ){
static std::vector<int> host_ips;

bb_int_t BBCALL bbCountHostIPs( BBStr *host ){
#ifndef WIN32
if( *host=="" ) *host="localhost";
#endif
host_ips.clear();
HOSTENT *h=gethostbyname( host->c_str() );
delete host;if( !h ) return 0;
Expand All @@ -380,19 +376,21 @@ bb_int_t BBCALL bbHostIP( bb_int_t index ){
}

UDPStream * BBCALL bbCreateUDPStream( bb_int_t port ){
#ifndef FIXME
if( !socks_ok ) return 0;
SOCKET s=::socket( AF_INET,SOCK_DGRAM,0 );
if( s!=INVALID_SOCKET ){
#ifndef BB_MACOS
sockaddr_in addr={AF_INET,htons(port)};
#else
sockaddr_in addr={sizeof(sockaddr_in),AF_INET,htons(port)};
#endif
if( !::bind( s,(sockaddr*)&addr,sizeof(addr) ) ){
UDPStream *p=d_new UDPStream( s );
udp_set.insert( p );
return p;
}
::closesocket( s );
}
#endif
return 0;
}

Expand Down Expand Up @@ -442,7 +440,6 @@ BBStr * BBCALL bbDottedIP( bb_int_t ip ){
itoa((ip>>8)&255)+"."+itoa(ip&255) );
}

#ifndef FIXME
static int findHostIP( const std::string &t ){
int ip=inet_addr( t.c_str() );
if( ip!=INADDR_NONE ) return ip;
Expand All @@ -454,10 +451,8 @@ static int findHostIP( const std::string &t ){
}
return 0;
}
#endif

TCPStream * BBCALL bbOpenTCPStream( BBStr *server,bb_int_t port,bb_int_t local_port ){
#ifndef FIXME
if( !socks_ok ){
delete server;
return 0;
Expand All @@ -467,22 +462,29 @@ TCPStream * BBCALL bbOpenTCPStream( BBStr *server,bb_int_t port,bb_int_t local_p
SOCKET s=::socket( AF_INET,SOCK_STREAM,0 );
if( s!=INVALID_SOCKET ){
if( local_port ){
#ifndef BB_MACOS
sockaddr_in addr={AF_INET,htons(local_port)};
#else
sockaddr_in addr={sizeof(sockaddr_in),AF_INET,htons(local_port)};
#endif
if( ::bind( s,(sockaddr*)&addr,sizeof(addr) ) ){
::closesocket( s );
return 0;
}
}
#ifndef BB_MACOS
sockaddr_in addr={AF_INET,htons(port)};
addr.sin_addr.S_un.S_addr=ip;
#else
sockaddr_in addr={sizeof(sockaddr_in),AF_INET,htons(port)};
#endif
S_ADDR(addr.sin_addr)=ip;
if( !::connect( s,(sockaddr*)&addr,sizeof(addr) ) ){
TCPStream *p=d_new TCPStream( s,0 );
tcp_set.insert( p );
return p;
}
::closesocket( s );
}
#endif
return 0;
}

Expand All @@ -493,10 +495,13 @@ void BBCALL bbCloseTCPStream( TCPStream *p ){
}

TCPServer * BBCALL bbCreateTCPServer( bb_int_t port ){
#ifndef FIXME
SOCKET s=::socket( AF_INET,SOCK_STREAM,0 );
if( s!=INVALID_SOCKET ){
#ifndef BB_MACOS
sockaddr_in addr={AF_INET,htons(port)};
#else
sockaddr_in addr={sizeof(sockaddr_in),AF_INET,htons(port)};
#endif
if( !::bind( s,(sockaddr*)&addr,sizeof(addr) ) ){
if( !::listen( s,SOMAXCONN ) ){
TCPServer *p=d_new TCPServer( s );
Expand All @@ -506,7 +511,6 @@ TCPServer * BBCALL bbCreateTCPServer( bb_int_t port ){
}
::closesocket(s);
}
#endif
return 0;
}

Expand Down Expand Up @@ -542,8 +546,10 @@ void BBCALL bbTCPTimeouts( bb_int_t rt,bb_int_t at ){
}

BBMODULE_CREATE( sockets ){
#ifndef FIXME
#ifdef WIN32
socks_ok=WSAStartup( 0x0101,&wsadata )==0;
#else
socks_ok=true;
#endif
recv_timeout=0;
read_timeout=10000;
Expand All @@ -555,7 +561,7 @@ BBMODULE_DESTROY( sockets ){
while( udp_set.size() ) bbCloseUDPStream( *udp_set.begin() );
while( tcp_set.size() ) bbCloseTCPStream( *tcp_set.begin() );
while( server_set.size() ) bbCloseTCPServer( *server_set.begin() );
#ifndef FIXME
#ifdef WIN32
if( socks_ok ) WSACleanup();
#endif
return true;
Expand Down
Loading

0 comments on commit 4848ddb

Please sign in to comment.