socket.cpp revision 4cb9ed4c3d183554e888e636844f8e3c2e666c40
/**
* Phoebe DOM Implementation.
*
* This is a C++ approximation of the W3C DOM model, which follows
* fairly closely the specifications in the various .idl files, copies of
* which are provided for reference. Most important is this one:
*
*
* Authors:
* Bob Jamison
*
* Copyright (C) 2005-2008 Bob Jamison
*
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_SYS_FILIO_H
#endif
#include <cstdio>
#include "socket.h"
#ifdef __WIN32__
#include <windows.h>
#else /* unix */
#include <netdb.h>
#include <unistd.h>
#endif
#ifdef HAVE_SSL
#endif
namespace org
{
namespace w3c
{
namespace dom
{
namespace io
{
{
unsigned char *p = (unsigned char *)s;
while (n > 0)
{
*p++ = (unsigned char)0;
n--;
}
}
{
unsigned char *p = (unsigned char *)dest;
unsigned char *q = (unsigned char *)src;
while (n > 0)
{
*p++ = *q++;
n--;
}
}
//#########################################################################
//# T C P C O N N E C T I O N
//#########################################################################
{
init();
}
{
init();
}
#ifdef HAVE_SSL
{
//printf("########### LOCK\n");
{
errstr = "invalid mode";
goto err;
}
{
errstr = "type out of bounds";
goto err;
}
if (mode & CRYPTO_LOCK)
{
{
errstr = "already locked";
/* must not happen in a single-threaded program
* (would deadlock)
*/
goto err;
}
}
else if (mode & CRYPTO_UNLOCK)
{
{
errstr = "not locked";
goto err;
}
{
"CRYPTO_r_unlock on write lock" :
"CRYPTO_w_unlock on read lock";
}
}
else
{
errstr = "invalid mode";
goto err;
}
err:
if (errstr)
{
/* we cannot use bio_err here */
}
}
static unsigned long cryptoIdCallback()
{
#ifdef __WIN32__
unsigned long ret = (unsigned long) GetCurrentThreadId();
#else
unsigned long ret = (unsigned long) pthread_self();
#endif
return ret;
}
#endif
{
init();
}
static bool tcp_socket_inited = false;
{
if (!tcp_socket_inited)
{
#ifdef __WIN32__
#endif
#ifdef HAVE_SSL
if (libssl_is_present)
{
sslContext = NULL;
}
#endif
tcp_socket_inited = true;
}
sock = -1;
connected = false;
hostname = "";
portno = -1;
sslEnabled = false;
receiveTimeout = 0;
}
{
disconnect();
}
bool TcpSocket::isConnected()
{
return false;
return true;
}
{
sslEnabled = val;
}
{
return connect();
}
#ifdef HAVE_SSL
/*
static int password_cb(char *buf, int bufLen, int rwflag, void *userdata)
{
char *password = "password";
if (bufLen < (int)(strlen(password)+1))
return 0;
strcpy(buf,password);
int ret = strlen(password);
return ret;
}
static void infoCallback(const SSL *ssl, int where, int ret)
{
switch (where)
{
case SSL_CB_ALERT:
{
printf("## %d SSL ALERT: %s\n", where, SSL_alert_desc_string_long(ret));
break;
}
default:
{
printf("## %d SSL: %s\n", where, SSL_state_string_long(ssl));
break;
}
}
}
*/
#endif
{
#ifdef HAVE_SSL
if (libssl_is_present)
{
sslContext = NULL;
//SSL_METHOD *meth = SSLv23_method();
//SSL_METHOD *meth = SSLv3_client_method();
//SSL_CTX_set_info_callback(sslContext, infoCallback);
#if 0
char *keyFile = "client.pem";
char *caList = "root.pem";
/* Load our keys and certificates*/
{
disconnect();
return false;
}
{
disconnect();
return false;
}
/* Load the CAs we trust*/
{
disconnect();
return false;
}
#endif
/* Connect the SSL socket */
if (SSL_connect(sslStream)<=0)
{
disconnect();
return false;
}
sslEnabled = true;
}
#endif /*HAVE_SSL*/
return true;
}
{
{
printf("open: null hostname\n");
return false;
}
if (portno<1)
{
printf("open: bad port number\n");
return false;
}
if (sock < 0)
{
printf("open: error creating socket\n");
return false;
}
if (!server)
{
return false;
}
struct sockaddr_in serv_addr;
if (ret < 0)
{
return false;
}
if (sslEnabled)
{
if (!startTls())
return false;
}
connected = true;
return true;
}
bool TcpSocket::disconnect()
{
bool ret = true;
connected = false;
#ifdef HAVE_SSL
if (libssl_is_present)
{
if (sslEnabled)
{
if (sslStream)
{
int r = SSL_shutdown(sslStream);
switch(r)
{
case 1:
break; /* Success */
case 0:
case -1:
default:
//printf("Shutdown failed");
ret = false;
}
}
if (sslContext)
}
sslContext = NULL;
}
#endif /*HAVE_SSL*/
#ifdef __WIN32__
#else
#endif
sock = -1;
sslEnabled = false;
return ret;
}
{
return true;
}
/**
* For normal sockets, return the number of bytes waiting to be received.
* For SSL, just return >0 when something is ready to be read.
*/
{
if (!isConnected())
return -1;
long count = 0;
#ifdef __WIN32__
return -1;
#else
return -1;
#endif
if (count<=0 && sslEnabled)
{
#ifdef HAVE_SSL
if (libssl_is_present)
{
return SSL_pending(sslStream);
}
#endif
}
return count;
}
{
if (!isConnected())
{
printf("write: socket closed\n");
return false;
}
unsigned char c = (unsigned char)ch;
if (sslEnabled)
{
#ifdef HAVE_SSL
if (libssl_is_present)
{
if (r<=0)
{
switch(SSL_get_error(sslStream, r))
{
default:
printf("SSL write problem");
return -1;
}
}
}
#endif
}
else
{
//if (send(sock, &c, 1, 0) < 0)
{
printf("write: could not send data\n");
return false;
}
}
return true;
}
{
if (!isConnected())
{
printf("write(str): socket closed\n");
return false;
}
if (sslEnabled)
{
#ifdef HAVE_SSL
if (libssl_is_present)
{
if (r<=0)
{
switch(SSL_get_error(sslStream, r))
{
default:
printf("SSL write problem");
return -1;
}
}
}
#endif
}
else
{
//if (send(sock, &c, 1, 0) < 0)
{
printf("write: could not send data\n");
return false;
}
}
return true;
}
{
if (!isConnected())
return -1;
//We'll use this loop for timeouts, so that SSL and plain sockets
//will behave the same way
if (receiveTimeout > 0)
{
unsigned long tim = 0;
while (true)
{
if (avail > 0)
break;
if (tim >= receiveTimeout)
return -2;
tim += 20;
}
}
//check again
if (!isConnected())
return -1;
unsigned char ch;
if (sslEnabled)
{
#ifdef HAVE_SSL
if (libssl_is_present)
{
if (!sslStream)
return -1;
switch (err)
{
case SSL_ERROR_NONE:
break;
case SSL_ERROR_ZERO_RETURN:
return -1;
case SSL_ERROR_SYSCALL:
printf("SSL read problem(syscall) %s\n",
return -1;
default:
printf("SSL read problem %s\n",
return -1;
}
}
#endif
}
else
{
if (ret <= 0)
{
if (ret<0)
printf("read: could not receive data\n");
disconnect();
return -1;
}
}
return (int)ch;
}
{
result = "";
while (isConnected())
{
if (ch<0)
return true;
{}
else if (ch=='\n')
return true;
else
}
return true;
}
} //namespace io
} //namespace dom
} //namespace w3c
} //namespace org
//#########################################################################
//# E N D O F F I L E
//#########################################################################