socket.cpp revision c3c835a405487c32c66ab5d68c3bca5517799405
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * Phoebe DOM Implementation.
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 * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith * Bob Jamison
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith * Copyright (C) 2005 Bob Jamison
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 * 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 * 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
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#else /* unix */
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith unsigned char *p = (unsigned char *)s;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith while (n > 0)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith *p++ = (unsigned char)0;
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smithstatic void mybcopy(void *src, void *dest, size_t n)
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith unsigned char *p = (unsigned char *)dest;
4ec6c08988d4f78cd72251f55b27f018823a5eeeLuke Smith unsigned char *q = (unsigned char *)src;
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith while (n > 0)
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith *p++ = *q++;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith//#########################################################################
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith//# T C P C O N N E C T I O N
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith//#########################################################################
b32d148b0052e1f874e9bc9803bef729bf859d97Luke SmithTcpSocket::TcpSocket(const DOMString &hostnameArg, int port)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithstatic void cryptoLockCallback(int mode, int type, const char *file, int line)
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith //printf("########### LOCK\n");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith /* must not happen in a single-threaded program
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith * (would deadlock)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith "CRYPTO_r_unlock on write lock" :
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith "CRYPTO_w_unlock on read lock";
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 Smithstatic unsigned long cryptoIdCallback()
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith unsigned long ret = (unsigned long) GetCurrentThreadId();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith unsigned long ret = (unsigned long) pthread_self();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithstatic bool tcp_socket_inited = false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithbool TcpSocket::connect(const DOMString &hostnameArg, int portnoArg)
0cd29719d36de1f7e3d0043f5d6fafb990a7b9e0Luke Smithstatic int password_cb(char *buf, int bufLen, int rwflag, void *userdata)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith char *password = "password";
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (bufLen < (int)(strlen(password)+1))
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith strcpy(buf,password);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith int ret = strlen(password);
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smithstatic void infoCallback(const SSL *ssl, int where, int ret)
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith switch (where)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith case SSL_CB_ALERT:
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("## %d SSL ALERT: %s\n", where, SSL_alert_desc_string_long(ret));
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("## %d SSL: %s\n", where, SSL_state_string_long(ssl));
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith //SSL_METHOD *meth = SSLv23_method();
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith //SSL_METHOD *meth = SSLv3_client_method();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith //SSL_CTX_set_info_callback(sslContext, infoCallback);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /* Load our keys and certificates*/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!(SSL_CTX_use_certificate_chain_file(sslContext, keyFile)))
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith fprintf(stderr, "Can't read certificate file\n");
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith SSL_CTX_set_default_passwd_cb(sslContext, password_cb);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!(SSL_CTX_use_PrivateKey_file(sslContext, keyFile, SSL_FILETYPE_PEM)))
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith /* Load the CAs we trust*/
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith if (!(SSL_CTX_load_verify_locations(sslContext, caList, 0)))
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith return false;
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith /* Connect the SSL socket */
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith#endif /*HAVE_SSL*/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith struct hostent *server = gethostbyname(c_hostname);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("open: could not locate host '%s'\n", c_hostname);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith mybcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith int ret = ::connect(sock, (const sockaddr *)&serv_addr, sizeof(serv_addr));
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith printf("open: could not connect to host '%s'\n", c_hostname);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith bool ret = true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith break; /* Success */
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith //printf("Shutdown failed");
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith#endif /*HAVE_SSL*/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithbool TcpSocket::setReceiveTimeout(unsigned long millis)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
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.
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith if (ioctlsocket(sock, FIONREAD, (unsigned long *)&count) != 0)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith unsigned char c = (unsigned char)ch;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith //if (send(sock, &c, 1, 0) < 0)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return false;
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith int r = SSL_write(sslStream, (unsigned char *)str.c_str(), len);
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith //if (send(sock, &c, 1, 0) < 0)
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith return false;
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith return true;
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith //We'll use this loop for timeouts, so that SSL and plain sockets
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith //will behave the same way
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith unsigned long tim = 0;
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith while (true)
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith //check again
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith unsigned char ch;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return (int)ch;
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith return true;
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith else if (ch=='\r') //we want canonical Net '\r\n' , so skip this
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith} //namespace io
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith} //namespace dom
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith} //namespace w3c
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith} //namespace org
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith//#########################################################################
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith//# E N D O F F I L E
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith//#########################################################################