socket.cpp revision c3c835a405487c32c66ab5d68c3bca5517799405
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith/**
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * Phoebe DOM Implementation.
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith *
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * This is a C++ approximation of the W3C DOM model, which follows
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * fairly closely the specifications in the various .idl files, copies of
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * which are provided for reference. Most important is this one:
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith *
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith *
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * Authors:
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * Bob Jamison
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith *
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith * Copyright (C) 2005 Bob Jamison
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith *
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * This library is free software; you can redistribute it and/or
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * modify it under the terms of the GNU Lesser General Public
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * License as published by the Free Software Foundation; either
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith * version 2.1 of the License, or (at your option) any later version.
01a9f856a72f90fbb8197384630b97bb93dc7473Luke Smith *
01a9f856a72f90fbb8197384630b97bb93dc7473Luke Smith * This library is distributed in the hope that it will be useful,
01a9f856a72f90fbb8197384630b97bb93dc7473Luke Smith * but WITHOUT ANY WARRANTY; without even the implied warranty of
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith * Lesser General Public License for more details.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith *
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith * You should have received a copy of the GNU Lesser General Public
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith * License along with this library; if not, write to the Free Software
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith */
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef HAVE_CONFIG_H
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#include <config.h>
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#endif
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#ifdef HAVE_SYS_FILIO_H
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#include <sys/filio.h> // needed on Solaris 8
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#endif
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#include "socket.h"
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#include "dom/util/thread.h"
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#ifdef __WIN32__
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#include <windows.h>
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#else /* unix */
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#include <sys/types.h>
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#include <sys/socket.h>
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#include <netinet/in.h>
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#include <netdb.h>
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#include <unistd.h>
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#include <sys/ioctl.h>
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#endif
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef HAVE_SSL
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#include <openssl/ssl.h>
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#include <openssl/err.h>
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#endif
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smithnamespace org
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith{
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smithnamespace w3c
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith{
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smithnamespace dom
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithnamespace io
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smithstatic void mybzero(void *s, size_t n)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith unsigned char *p = (unsigned char *)s;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith while (n > 0)
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith *p++ = (unsigned char)0;
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith n--;
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith }
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith}
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smithstatic void mybcopy(void *src, void *dest, size_t n)
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith{
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith unsigned char *p = (unsigned char *)dest;
4ec6c08988d4f78cd72251f55b27f018823a5eeeLuke Smith unsigned char *q = (unsigned char *)src;
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith while (n > 0)
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith {
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith *p++ = *q++;
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith n--;
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith }
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith}
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith//#########################################################################
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith//# T C P C O N N E C T I O N
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith//#########################################################################
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke SmithTcpSocket::TcpSocket()
9327ef7ad1fee11b0e494b97cc07386565326c03Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith init();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke SmithTcpSocket::TcpSocket(const DOMString &hostnameArg, int port)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith init();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith hostname = hostnameArg;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith portno = port;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef HAVE_SSL
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithstatic void cryptoLockCallback(int mode, int type, const char *file, int line)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith //printf("########### LOCK\n");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith const char *errstr = NULL;
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith int rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith errstr = "invalid mode";
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith goto err;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith if (type < 0 || type >= CRYPTO_NUM_LOCKS)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith errstr = "type out of bounds";
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith goto err;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (mode & CRYPTO_LOCK)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (modes[type])
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith errstr = "already locked";
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith /* must not happen in a single-threaded program
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith * (would deadlock)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith */
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith goto err;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith modes[type] = rw;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith else if (mode & CRYPTO_UNLOCK)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!modes[type])
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith errstr = "not locked";
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith goto err;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (modes[type] != rw)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith errstr = (rw == CRYPTO_READ) ?
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith "CRYPTO_r_unlock on write lock" :
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith "CRYPTO_w_unlock on read lock";
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith modes[type] = 0;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith else
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith errstr = "invalid mode";
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith goto err;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith err:
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (errstr)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /* we cannot use bio_err here */
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith errstr, mode, type, file, line);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithstatic unsigned long cryptoIdCallback()
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef __WIN32__
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith unsigned long ret = (unsigned long) GetCurrentThreadId();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#else
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith unsigned long ret = (unsigned long) pthread_self();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return ret;
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke SmithTcpSocket::TcpSocket(const TcpSocket &other)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith init();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sock = other.sock;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith hostname = other.hostname;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith portno = other.portno;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithstatic bool tcp_socket_inited = false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithvoid TcpSocket::init()
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!tcp_socket_inited)
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef __WIN32__
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith WORD wVersionRequested = MAKEWORD( 2, 2 );
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith WSADATA wsaData;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith WSAStartup( wVersionRequested, &wsaData );
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef HAVE_SSL
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslStream = NULL;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslContext = NULL;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith CRYPTO_set_locking_callback(cryptoLockCallback);
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith CRYPTO_set_id_callback(cryptoIdCallback);
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith SSL_library_init();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith SSL_load_error_strings();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith tcp_socket_inited = true;
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sock = -1;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith connected = false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith hostname = "";
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith portno = -1;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslEnabled = false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith receiveTimeout = 0;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke SmithTcpSocket::~TcpSocket()
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith{
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith disconnect();
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithbool TcpSocket::isConnected()
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!connected || sock < 0)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithvoid TcpSocket::enableSSL(bool val)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslEnabled = val;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithbool TcpSocket::connect(const DOMString &hostnameArg, int portnoArg)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith hostname = hostnameArg;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith portno = portnoArg;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return connect();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef HAVE_SSL
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith/*
0cd29719d36de1f7e3d0043f5d6fafb990a7b9e0Luke Smithstatic int password_cb(char *buf, int bufLen, int rwflag, void *userdata)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith char *password = "password";
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (bufLen < (int)(strlen(password)+1))
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return 0;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith strcpy(buf,password);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith int ret = strlen(password);
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith return ret;
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smithstatic void infoCallback(const SSL *ssl, int where, int ret)
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith{
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith switch (where)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith case SSL_CB_ALERT:
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("## %d SSL ALERT: %s\n", where, SSL_alert_desc_string_long(ret));
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith break;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith default:
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("## %d SSL: %s\n", where, SSL_state_string_long(ssl));
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith break;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith*/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithbool TcpSocket::startTls()
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef HAVE_SSL
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslStream = NULL;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslContext = NULL;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith //SSL_METHOD *meth = SSLv23_method();
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith //SSL_METHOD *meth = SSLv3_client_method();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith SSL_METHOD *meth = TLSv1_client_method();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslContext = SSL_CTX_new(meth);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith //SSL_CTX_set_info_callback(sslContext, infoCallback);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#if 0
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith char *keyFile = "client.pem";
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith char *caList = "root.pem";
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /* Load our keys and certificates*/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!(SSL_CTX_use_certificate_chain_file(sslContext, keyFile)))
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith fprintf(stderr, "Can't read certificate file\n");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith disconnect();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith SSL_CTX_set_default_passwd_cb(sslContext, password_cb);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!(SSL_CTX_use_PrivateKey_file(sslContext, keyFile, SSL_FILETYPE_PEM)))
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith fprintf(stderr, "Can't read key file\n");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith disconnect();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith /* Load the CAs we trust*/
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith if (!(SSL_CTX_load_verify_locations(sslContext, caList, 0)))
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith {
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith fprintf(stderr, "Can't read CA list\n");
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith disconnect();
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith return false;
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith }
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith#endif
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith /* Connect the SSL socket */
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith sslStream = SSL_new(sslContext);
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith SSL_set_fd(sslStream, sock);
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith if (SSL_connect(sslStream)<=0)
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith {
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith fprintf(stderr, "SSL connect error\n");
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith disconnect();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslEnabled = true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif /*HAVE_SSL*/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smithbool TcpSocket::connect()
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (hostname.size()<1)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("open: null hostname\n");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (portno<1)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith printf("open: bad port number\n");
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith return false;
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sock = socket(PF_INET, SOCK_STREAM, 0);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (sock < 0)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("open: error creating socket\n");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith char *c_hostname = (char *)hostname.c_str();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith struct hostent *server = gethostbyname(c_hostname);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!server)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("open: could not locate host '%s'\n", c_hostname);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith struct sockaddr_in serv_addr;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith mybzero((char *) &serv_addr, sizeof(serv_addr));
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith serv_addr.sin_family = AF_INET;
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith mybcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith server->h_length);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith serv_addr.sin_port = htons(portno);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith int ret = ::connect(sock, (const sockaddr *)&serv_addr, sizeof(serv_addr));
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (ret < 0)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("open: could not connect to host '%s'\n", c_hostname);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (sslEnabled)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!startTls())
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith connected = true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithbool TcpSocket::disconnect()
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith bool ret = true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith connected = false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef HAVE_SSL
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (sslEnabled)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (sslStream)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith int r = SSL_shutdown(sslStream);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith switch(r)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith case 1:
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith break; /* Success */
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith case 0:
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith case -1:
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith default:
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith //printf("Shutdown failed");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith ret = false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith SSL_free(sslStream);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (sslContext)
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith SSL_CTX_free(sslContext);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslStream = NULL;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslContext = NULL;
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith#endif /*HAVE_SSL*/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef __WIN32__
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith closesocket(sock);
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith#else
9327ef7ad1fee11b0e494b97cc07386565326c03Luke Smith ::close(sock);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sock = -1;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith sslEnabled = false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return ret;
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith}
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithbool TcpSocket::setReceiveTimeout(unsigned long millis)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith receiveTimeout = millis;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith/**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith * For normal sockets, return the number of bytes waiting to be received.
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith * For SSL, just return >0 when something is ready to be read.
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith */
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smithlong TcpSocket::available()
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith{
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith if (!isConnected())
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith return -1;
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith long count = 0;
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith#ifdef __WIN32__
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith if (ioctlsocket(sock, FIONREAD, (unsigned long *)&count) != 0)
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith return -1;
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith#else
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith if (ioctl(sock, FIONREAD, &count) != 0)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return -1;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (count<=0 && sslEnabled)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef HAVE_SSL
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return SSL_pending(sslStream);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return count;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithbool TcpSocket::write(int ch)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!isConnected())
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("write: socket closed\n");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith unsigned char c = (unsigned char)ch;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (sslEnabled)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef HAVE_SSL
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith int r = SSL_write(sslStream, &c, 1);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (r<=0)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith switch(SSL_get_error(sslStream, r))
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith default:
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("SSL write problem");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return -1;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith else
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (send(sock, (const char *)&c, 1, 0) < 0)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith //if (send(sock, &c, 1, 0) < 0)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("write: could not send data\n");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithbool TcpSocket::write(const DOMString &strArg)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith DOMString str = strArg;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!isConnected())
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("write(str): socket closed\n");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith int len = str.size();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (sslEnabled)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#ifdef HAVE_SSL
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith int r = SSL_write(sslStream, (unsigned char *)str.c_str(), len);
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith if (r<=0)
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith {
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith switch(SSL_get_error(sslStream, r))
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith {
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith default:
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith printf("SSL write problem");
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith return -1;
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith }
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith }
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith#endif
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith }
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith else
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith {
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith if (send(sock, str.c_str(), len, 0) < 0)
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith //if (send(sock, &c, 1, 0) < 0)
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith {
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith printf("write: could not send data\n");
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith return false;
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith }
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith }
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith return true;
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith}
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smithint TcpSocket::read()
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith{
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith if (!isConnected())
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith return -1;
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith //We'll use this loop for timeouts, so that SSL and plain sockets
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith //will behave the same way
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith if (receiveTimeout > 0)
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith {
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith unsigned long tim = 0;
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith while (true)
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith {
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith int avail = available();
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith if (avail > 0)
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith break;
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith if (tim >= receiveTimeout)
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith return -2;
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith org::w3c::dom::util::Thread::sleep(20);
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith tim += 20;
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith }
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith }
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith //check again
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith if (!isConnected())
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith return -1;
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith unsigned char ch;
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith if (sslEnabled)
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith {
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith#ifdef HAVE_SSL
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith if (!sslStream)
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith return -1;
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith int r = SSL_read(sslStream, &ch, 1);
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith unsigned long err = SSL_get_error(sslStream, r);
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith switch (err)
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith {
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith case SSL_ERROR_NONE:
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith break;
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith case SSL_ERROR_ZERO_RETURN:
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith return -1;
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith case SSL_ERROR_SYSCALL:
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith printf("SSL read problem(syscall) %s\n",
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith ERR_error_string(ERR_get_error(), NULL));
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith return -1;
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith default:
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith printf("SSL read problem %s\n",
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith ERR_error_string(ERR_get_error(), NULL));
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith return -1;
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith }
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith#endif
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith }
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith else
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith {
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith int ret = recv(sock, (char *)&ch, 1, 0);
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith if (ret <= 0)
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith {
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith if (ret<0)
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith printf("read: could not receive data\n");
08299549a01ea998d0fc3bfbf97c5ff4d351f543Luke Smith disconnect();
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith return -1;
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return (int)ch;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithbool TcpSocket::readLine(DOMString &result)
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith{
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith result = "";
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith while (isConnected())
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith {
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith int ch = read();
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith if (ch<0)
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith return true;
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith else if (ch=='\r') //we want canonical Net '\r\n' , so skip this
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith {}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith else if (ch=='\n')
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith else
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith result.push_back((char)ch);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith} //namespace io
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith} //namespace dom
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith} //namespace w3c
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith} //namespace org
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith//#########################################################################
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith//# E N D O F F I L E
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith//#########################################################################
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith