--- /dev/null
+/* IOSSLBackend.c - IOMultiplexer
+ * Copyright (C) 2014 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#define _IOHandler_internals
+#include "IOInternal.h"
+#include "IOHandler.h"
+#include "IOLog.h"
+#include "IOSockets.h"
+#include "IOSSLBackend.h"
+
+#ifdef HAVE_OPENSSL_SSL_H
+/* OpenSSL Backend */
+
+
+void iossl_init() {
+ SSL_library_init();
+ OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
+ SSL_load_error_strings();
+}
+
+static void iossl_error() {
+ unsigned long e;
+ while((e = ERR_get_error())) {
+ iolog_trigger(IOLOG_ERROR, "SSLv23 ERROR %lu: %s", e, ERR_error_string(e, NULL));
+ }
+}
+
+// Client
+void iossl_connect(struct _IOSocket *iosock) {
+ struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
+ sslnode->sslContext = SSL_CTX_new(SSLv23_client_method());
+ if(!sslnode->sslContext) {
+ iossl_error();
+ iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL CTX");
+ goto ssl_connect_err;
+ }
+ sslnode->sslHandle = SSL_new(sslnode->sslContext);
+ if(!sslnode->sslHandle) {
+ iossl_error();
+ iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL Handle");
+ goto ssl_connect_err;
+ }
+ if(!SSL_set_fd(sslnode->sslHandle, iosock->fd)) {
+ iossl_error();
+ iolog_trigger(IOLOG_ERROR, "SSL: could not set client fd in SSL Handle");
+ goto ssl_connect_err;
+ }
+ SSL_set_connect_state(sslnode->sslHandle);
+ iosock->sslnode = sslnode;
+ iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
+ iossl_client_handshake(iosock);
+ return;
+ssl_connect_err:
+ free(sslnode);
+ iosocket_events_callback(iosock, 0, 0);
+}
+
+void iossl_client_handshake(struct _IOSocket *iosock) {
+ // Perform an SSL handshake.
+ int ret = SSL_do_handshake(iosock->sslnode->sslHandle);
+ iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
+ switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
+ case SSL_ERROR_NONE:
+ iolog_trigger(IOLOG_DEBUG, "SSL handshake for fd %d successful", iosock->fd);
+ iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
+ iosocket_events_callback(iosock, 0, 0); //perform IOEVENT_CONNECTED event
+ break;
+ case SSL_ERROR_WANT_READ:
+ iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE;
+ iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
+ break;
+ default:
+ iolog_trigger(IOLOG_ERROR, "SSL_do_handshake for fd %d failed with ", iosock->fd);
+ iosocket_events_callback(iosock, 0, 0);
+ break;
+ }
+}
+
+
+// Server
+void iossl_listen(struct _IOSocket *iosock, const char *certfile, const char *keyfile) {
+ struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
+ sslnode->sslContext = SSL_CTX_new(SSLv23_server_method());
+ if(!sslnode->sslContext) {
+ iossl_error();
+ iolog_trigger(IOLOG_ERROR, "SSL: could not create server SSL CTX");
+ goto ssl_listen_err;
+ }
+ /* load certificate */
+ if(SSL_CTX_use_certificate_file(sslnode->sslContext, certfile, SSL_FILETYPE_PEM) <= 0) {
+ iossl_error();
+ iolog_trigger(IOLOG_ERROR, "SSL: could not load server certificate (%s)", certfile);
+ goto ssl_listen_err;
+ }
+ /* load keyfile */
+ if(SSL_CTX_use_PrivateKey_file(sslnode->sslContext, keyfile, SSL_FILETYPE_PEM) <= 0) {
+ iossl_error();
+ iolog_trigger(IOLOG_ERROR, "SSL: could not load server keyfile (%s)", keyfile);
+ goto ssl_listen_err;
+ }
+ /* check certificate and keyfile */
+ if(!SSL_CTX_check_private_key(sslnode->sslContext)) {
+ iossl_error();
+ iolog_trigger(IOLOG_ERROR, "SSL: server certificate (%s) and keyfile (%s) doesn't match!", certfile, keyfile);
+ goto ssl_listen_err;
+ }
+ iosock->sslnode = sslnode;\r
+ iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
+ return;
+ssl_listen_err:
+ free(sslnode);
+ iosock->sslnode = NULL;
+ iosocket_events_callback(iosock, 0, 0);
+}
+
+void iossl_client_accepted(struct _IOSocket *iosock, struct _IOSocket *new_iosock) {
+ struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
+ sslnode->sslHandle = SSL_new(sslnode->sslContext);
+ if(!sslnode->sslHandle) {
+ iossl_error();
+ iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL Handle");
+ goto ssl_accept_err;
+ }
+ if(!SSL_set_fd(sslnode->sslHandle, new_iosock->fd)) {
+ iossl_error();
+ iolog_trigger(IOLOG_ERROR, "SSL: could not set client fd in SSL Handle");
+ goto ssl_accept_err;
+ }
+ new_iosock->sslnode = sslnode;\r
+ new_iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
+ return;
+ssl_accept_err:
+ free(sslnode);\r
+ iosock->sslnode = NULL;\r
+ iosocket_events_callback(new_iosock, 0, 0);
+}
+
+void iossl_server_handshake(struct _IOSocket *iosock) {
+ // Perform an SSL handshake.
+ int ret = SSL_accept(iosock->sslnode->sslHandle);
+ iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
+ switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
+ case SSL_ERROR_NONE:
+ iolog_trigger(IOLOG_DEBUG, "SSL handshake for fd %d successful", iosock->fd);
+ iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
+ iosocket_events_callback(iosock, 0, 0); //perform IOEVENT_CONNECTED event
+ break;
+ case SSL_ERROR_WANT_READ:
+ iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE;
+ iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
+ break;
+ default:
+ iolog_trigger(IOLOG_ERROR, "SSL_do_handshake for fd %d failed with ", iosock->fd);
+ iosocket_events_callback(iosock, 0, 0);
+ break;
+ }
+}
+
+void iossl_disconnect(struct _IOSocket *iosock) {
+ if(!iosock->sslnode) return;
+ SSL_shutdown(iosock->sslnode->sslHandle);
+ SSL_free(iosock->sslnode->sslHandle);
+ SSL_CTX_free(iosock->sslnode->sslContext);
+ free(iosock->sslnode);
+ iosock->sslnode = NULL;
+ iosock->socket_flags &= ~IOSOCKETFLAG_SSLSOCKET;
+}
+
+int iossl_read(struct _IOSocket *iosock, char *buffer, int len) {
+ if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))\r
+ return 0;
+ int ret = SSL_read(iosock->sslnode->sslHandle, buffer, len);
+ iosock->socket_flags &= ~(IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_READHS);
+ switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_ZERO_RETURN:
+ break;
+ case SSL_ERROR_WANT_READ:\r
+ iosock->socket_flags |= IOSOCKETFLAG_SSL_READHS;
+ iolog_trigger(IOLOG_DEBUG, "SSL_read for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
+ errno = EAGAIN;
+ ret = -1;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_READHS;
+ iolog_trigger(IOLOG_DEBUG, "SSL_read for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
+ errno = EAGAIN;
+ ret = -1;
+ break;
+ default:
+ iolog_trigger(IOLOG_ERROR, "SSL_read for fd %d failed with ", iosock->fd);
+ ret = -1;
+ break;
+ }\r
+ return ret;
+}
+
+int iossl_write(struct _IOSocket *iosock, char *buffer, int len) {
+ if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))\r
+ return 0;
+ int ret = SSL_write(iosock->sslnode->sslHandle, buffer, len);
+ iosock->socket_flags &= ~(IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_WRITEHS);
+ switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_ZERO_RETURN:
+ break;
+ case SSL_ERROR_WANT_READ:
+ iosock->socket_flags |= IOSOCKETFLAG_SSL_WRITEHS;
+ iolog_trigger(IOLOG_DEBUG, "SSL_write for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
+ errno = EAGAIN;
+ ret = -1;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_WRITEHS;
+ iolog_trigger(IOLOG_DEBUG, "SSL_write for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
+ errno = EAGAIN;
+ ret = -1;
+ break;
+ default:
+ iolog_trigger(IOLOG_ERROR, "SSL_write for fd %d failed with ", iosock->fd);
+ ret = -1;
+ break;
+ }\r
+ return ret;
+}
+
+#else
+// NULL-backend
+
+void iossl_init() {};
+void iossl_connect(struct _IOSocket *iosock) {};
+void iossl_listen(struct _IOSocket *iosock, const char *certfile, const char *keyfile) {};
+void iossl_client_handshake(struct _IOSocket *iosock) {};
+void iossl_client_accepted(struct _IOSocket *iosock, struct IODescriptor *client_iofd) {};
+void iossl_server_handshake(struct _IOSocket *iosock) {};
+void iossl_disconnect(struct _IOSocket *iosock) {};
+int iossl_read(struct _IOSocket *iosock, char *buffer, int len) { return 0; };
+int iossl_write(struct _IOSocket *iosock, char *buffer, int len) { return 0; };
+#endif
--- /dev/null
+/* IOHandler_SSL.h - IOMultiplexer
+ * Copyright (C) 2014 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _IOSSLBackend_h
+#define _IOSSLBackend_h
+
+struct _IOSocket;
+
+#ifdef HAVE_OPENSSL_SSL_H
+#include <openssl/rand.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+struct IOSSLDescriptor {
+ unsigned int flags : 8;
+ SSL *sslHandle;
+ SSL_CTX *sslContext;
+};
+#else
+struct IOSSLDescriptor {
+ //just unused
+};
+#endif
+
+void iossl_init();
+void iossl_connect(struct _IOSocket *iosock);
+void iossl_listen(struct _IOSocket *iosock, const char *certfile, const char *keyfile);
+void iossl_client_handshake(struct _IOSocket *iosock);
+void iossl_client_accepted(struct _IOSocket *iosock, struct _IOSocket *new_iosock);
+void iossl_server_handshake(struct _IOSocket *iosock);
+void iossl_disconnect(struct _IOSocket *iosock);
+int iossl_read(struct _IOSocket *iosock, char *buffer, int len);
+int iossl_write(struct _IOSocket *iosock, char *buffer, int len);
+
+#endif
}
#endif
- iosockets_init_engine();
+ iosockets_init_engine();\r
+ iossl_init();
}
free(iosock->readbuf.buffer);
if(iosock->writebuf.buffer)
free(iosock->writebuf.buffer);
+ if((iosock->socket_flags & IOSOCKETFLAG_SSLSOCKET))\r
+ iossl_disconnect(iosock);\r
free(iosock);
}
if((iosock->socket_flags & IOSOCKETFLAG_SSLSOCKET)) {
new_iosocket->ssl = 1;
new_iosock->socket_flags |= IOSOCKETFLAG_SSLSOCKET;
- //TODO: SSL Handshake
+ \r
+ iossl_client_accepted(iosock, new_iosock);
}
iosocket_activate(new_iosock);
iosock->parent = iodescriptor;
iosock->socket_flags |= IOSOCKETFLAG_PARENT_PUBLIC | IOSOCKETFLAG_LISTENING;
iosock->port = port;
- /*
- if(ssl) {
- iodescriptor->ssl = 1;
- iosock->socket_flags |= IOSOCKETFLAG_SSLSOCKET;
- }
- */
switch(iosocket_parse_address(hostname, &iosock->bind.addr, flags)) {
case -1:
}
struct IOSocket *iosocket_listen_ssl_flags(const char *hostname, unsigned int port, const char *certfile, const char *keyfile, iosocket_callback *callback, int flags) {
- //TODO: SSL
- return NULL;
+ struct IOSocket *iosocket = iosocket_listen_flags(hostname, port, callback, flags);\r
+ struct _IOSocket *iosock = iosocket->iosocket;\r
+ iosock->socket_flags |= IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_HANDSHAKE;\r
+ iossl_listen(iosock, certfile, keyfile);
+ return iosocket;
}
void iosocket_close(struct IOSocket *iosocket) {
iosocket_try_write(iosock);
}
//close IOSocket
- if(iosock->sslnode) {
- //TODO: SSL
- }
+ if((iosock->socket_flags & IOSOCKETFLAG_SSLSOCKET))
+ iossl_disconnect(iosock);
if(iosock->fd)
close(iosock->fd);
_free_socket(iosock);
}
static int iosocket_try_write(struct _IOSocket *iosock) {
- if(!iosock->writebuf.bufpos) return 0;
+ if(!iosock->writebuf.bufpos && !(iosock->socket_flags & IOSOCKETFLAG_SSL_WRITEHS)) \r
+ return 0;
iolog_trigger(IOLOG_DEBUG, "write writebuf (%d bytes) to socket (fd: %d)", iosock->writebuf.bufpos, iosock->fd);
int res;
- if(iosock->sslnode) {
- /* res = iohandler_ssl_write(iofd, iofd->writebuf.buffer, iofd->writebuf.bufpos); */
- // TODO
- } else
+ if((iosock->socket_flags & IOSOCKETFLAG_SSLSOCKET))
+ res = iossl_write(iosock, iosock->writebuf.buffer, iosock->writebuf.bufpos);
+ else
res = send(iosock->fd, iosock->writebuf.buffer, iosock->writebuf.bufpos, 0);
if(res < 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK)
int pos;
sendBuf[0] = '\0';
va_start(arg_list, text);
- pos = vsnprintf(sendBuf, IOSOCKET_PRINTF_LINE_LEN - 2, text, arg_list);
+ pos = vsnprintf(sendBuf, IOSOCKET_PRINTF_LINE_LEN - 1, text, arg_list);
va_end(arg_list);
- if (pos < 0 || pos > (IOSOCKET_PRINTF_LINE_LEN - 2)) pos = IOSOCKET_PRINTF_LINE_LEN - 2;
- sendBuf[pos] = '\n';
- sendBuf[pos+1] = '\0';
- iosocket_send(iosocket, sendBuf, pos+1);
+ if (pos < 0 || pos > (IOSOCKET_PRINTF_LINE_LEN - 1)) pos = IOSOCKET_PRINTF_LINE_LEN - 1;
+ sendBuf[pos] = '\0';
+ iosocket_send(iosocket, sendBuf, pos);
}
callback_event.socket = iosocket;
if((iosock->socket_flags & IOSOCKETFLAG_SSL_HANDSHAKE)) {
- //TODO: SSL
+ if(readable || writeable) {
+ if((iosock->socket_flags & IOSOCKETFLAG_INCOMING))
+ iossl_server_handshake(iosock);
+ else
+ iossl_client_handshake(iosock);
+ engine->update(iosock);\r
+ } else if((iosock->socket_flags & IOSOCKETFLAG_LISTENING)) {\r
+ //TODO: SSL init error\r
+ } else if((iosock->socket_flags & IOSOCKETFLAG_INCOMING)) {\r
+ if((iosock->socket_flags & IOSOCKETFLAG_SSL_ESTABLISHED)) {\r
+ //incoming SSL connection accepted\r
+ iosock->socket_flags &= ~IOSOCKETFLAG_SSL_HANDSHAKE;\r
+ callback_event.type = IOSOCKETEVENT_ACCEPT;\r
+ callback_event.data.accept_socket = iosock->parent;\r
+ } else {\r
+ //incoming SSL connection failed, simply drop\r
+ iosock->socket_flags |= IOSOCKETFLAG_DEAD;\r
+ iolog_trigger(IOLOG_ERROR, "SSL Handshake failed for incoming connection. Dropping fd %d", iosock->fd);\r
+ }
+ } else {
+ // SSL Backend finished
+ if((iosock->socket_flags & IOSOCKETFLAG_SSL_ESTABLISHED)) {\r
+ iosocket->status = IOSOCKET_CONNECTED;\r
+ iosock->socket_flags &= ~IOSOCKETFLAG_SSL_HANDSHAKE;\r
+ callback_event.type = IOSOCKETEVENT_CONNECTED;\r
+ engine->update(iosock);\r
+ \r
+ //initialize readbuf\r
+ iosocket_increase_buffer(&iosock->readbuf, 1024);
+ } else {
+ callback_event.type = IOSOCKETEVENT_NOTCONNECTED;\r
+ iosock->socket_flags |= IOSOCKETFLAG_DEAD;
+ }
+ }
} else if((iosock->socket_flags & IOSOCKETFLAG_LISTENING)) {
if(readable) {
//new client connected
iosock->socket_flags |= IOSOCKETFLAG_DEAD;
}
} else if(writeable) { //connection established
- iosocket->status = IOSOCKET_CONNECTED;
- if((iosock->socket_flags & IOSOCKETFLAG_SSLSOCKET)) {
- //TODO: SSL Handshake
+ iosock->socket_flags &= ~IOSOCKETFLAG_CONNECTING;
+ socket_lookup_clear(iosock);
+ if((iosock->socket_flags & IOSOCKETFLAG_SSLSOCKET)) {\r
+ iolog_trigger(IOLOG_DEBUG, "SSL client socket connected. Stating SSL handshake...");
+ iossl_connect(iosock);
+ engine->update(iosock);
return;
}
+ iosocket->status = IOSOCKET_CONNECTED;
callback_event.type = IOSOCKETEVENT_CONNECTED;
- iosock->socket_flags &= ~IOSOCKETFLAG_CONNECTING;
- socket_lookup_clear(iosock);
engine->update(iosock);
//initialize readbuf
iosocket_increase_buffer(&iosock->readbuf, 1024);
}
- } else {
- if(readable) {
+ } else {\r
+ int ssl_rehandshake = 0;\r
+ if((iosock->socket_flags & IOSOCKETFLAG_SSLSOCKET)) {\r
+ if((iosock->socket_flags & IOSOCKETFLAG_SSL_READHS))\r
+ ssl_rehandshake = 1;\r
+ else if((iosock->socket_flags & IOSOCKETFLAG_SSL_WRITEHS))\r
+ ssl_rehandshake = 2;\r
+ }
+ if((readable && ssl_rehandshake == 0) || ssl_rehandshake == 1) {
int bytes;
if(iosock->readbuf.buflen - iosock->readbuf.bufpos >= 128)
iosocket_increase_buffer(&iosock->readbuf, iosock->readbuf.buflen + 1024);
- if((iosock->socket_flags & IOSOCKETFLAG_SSLSOCKET)) {
- //TODO: SSL read
- } else
+ if((iosock->socket_flags & IOSOCKETFLAG_SSLSOCKET))
+ bytes = iossl_read(iosock, iosock->readbuf.buffer + iosock->readbuf.bufpos, iosock->readbuf.buflen - iosock->readbuf.bufpos);
+ else
bytes = recv(iosock->fd, iosock->readbuf.buffer + iosock->readbuf.bufpos, iosock->readbuf.buflen - iosock->readbuf.bufpos, 0);
- if(bytes <= 0) {
- if (errno != EAGAIN || errno != EWOULDBLOCK) {
+ if(bytes <= 0) {\r
+ if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_READHS)) == (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_READHS)) {\r
+ ssl_rehandshake = 1;\r
+ } else if (errno != EAGAIN || errno != EWOULDBLOCK) {
iosock->socket_flags |= IOSOCKETFLAG_DEAD;
callback_event.type = IOSOCKETEVENT_CLOSED;
callback_event.data.recv_buf = &iosock->readbuf;
}
}
- if(writeable) {
+ if((writeable && ssl_rehandshake == 0) || ssl_rehandshake == 2) {
int bytes;
bytes = iosocket_try_write(iosock);
- if(bytes < 0) {
- iosock->socket_flags |= IOSOCKETFLAG_DEAD;
-
- callback_event.type = IOSOCKETEVENT_CLOSED;
- callback_event.data.errid = errno;
+ if(bytes < 0) {\r
+ if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_WRITEHS)) == (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_WRITEHS)) {\r
+ ssl_rehandshake = 1;\r
+ } else {
+ iosock->socket_flags |= IOSOCKETFLAG_DEAD;
+
+ callback_event.type = IOSOCKETEVENT_CLOSED;
+ callback_event.data.errid = errno;\r
+ }
}
+ }\r
+ if(ssl_rehandshake) {
+ engine->update(iosock);\r
}
-
}
if(callback_event.type != IOSOCKETEVENT_IGNORE)
iosocket_trigger_event(&callback_event);
#define IOSOCKETFLAG_PARENT_DNSENGINE 0x0200
#define IOSOCKETFLAG_SSLSOCKET 0x0400 /* use ssl after connecting */
#define IOSOCKETFLAG_SSL_HANDSHAKE 0x0800 /* SSL Handshake in progress */
-#define IOSOCKETFLAG_SSL_WANTWRITE 0x1000
-#define IOSOCKETFLAG_SHUTDOWN 0x2000 /* disconnect pending */
-#define IOSOCKETFLAG_CONNECTING 0x4000
-#define IOSOCKETFLAG_INCOMING 0x8000 /* incoming (accepted) connection */
-#define IOSOCKETFLAG_DEAD 0x10000
-#define IOSOCKETFLAG_RECONNECT_IPV4 0x20000 /* possible fallback to ipv4 connect if ipv6 fails */
+#define IOSOCKETFLAG_SSL_WANTWRITE 0x1000\r
+#define IOSOCKETFLAG_SSL_READHS 0x2000 /* ssl read rehandshake */\r
+#define IOSOCKETFLAG_SSL_WRITEHS 0x4000 /* ssl write rehandshake */
+#define IOSOCKETFLAG_SSL_ESTABLISHED 0x8000
+#define IOSOCKETFLAG_SHUTDOWN 0x10000 /* disconnect pending */
+#define IOSOCKETFLAG_CONNECTING 0x20000
+#define IOSOCKETFLAG_INCOMING 0x40000 /* incoming (accepted) connection */
+#define IOSOCKETFLAG_DEAD 0x80000
+#define IOSOCKETFLAG_RECONNECT_IPV4 0x100000 /* possible fallback to ipv4 connect if ipv6 fails */
struct IOSocketDNSLookup {
unsigned int bindlookup : 1;
void iosocket_loop(int usec);
void iosocket_lookup_callback(struct IOSocketDNSLookup *lookup, struct IODNSEvent *event);
void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writeable);
-
-#define iosocket_wants_writes(IOSOCK) (IOSOCK->writebuf.bufpos || (IOSOCK->socket_flags & (IOSOCKETFLAG_CONNECTING | IOSOCKETFLAG_SSL_WANTWRITE)))
+\r
+#define iosocket_wants_writes(IOSOCK) ((IOSOCK->writebuf.bufpos && !(IOSOCK->socket_flags & (IOSOCKETFLAG_SSL_READHS | IOSOCKETFLAG_SSL_WRITEHS))) || (IOSOCK->socket_flags & (IOSOCKETFLAG_CONNECTING | IOSOCKETFLAG_SSL_WANTWRITE)))
#endif
IOSOCKET_CLOSED, /* descriptor is dead (socket waiting for removal or timer) */
IOSOCKET_LISTENING, /* descriptor is waiting for connections (server socket) */
IOSOCKET_CONNECTING, /* descriptor is waiting for connection approval (connecting client socket) */
- IOSOCKET_CONNECTED /* descriptor is connected (connected client socket) */
+ IOSOCKET_CONNECTED, /* descriptor is connected (connected client socket) */
+ IOSOCKET_SSLHANDSHAKE /* descriptor is waiting for ssl (handshake) */
};
enum IOSocketEventType {
IOSOCKETEVENT_NOTCONNECTED, /* client socket could not connect (errid valid) */
IOSOCKETEVENT_CLOSED, /* client socket lost connection (errid valid) */
IOSOCKETEVENT_ACCEPT, /* server socket accepted new connection (accept_socket valid) */
- IOSOCKETEVENT_SSLFAILED, /* failed to initialize SSL session */
IOSOCKETEVENT_DNSFAILED /* failed to lookup DNS information (recv_str contains error message) */
};
IOGarbageCollector.c \
IOLog.c \
IOSockets.c \
+ IOSSLBackend.c \
IOTimer.c
noinst_LIBRARIES = libiohandler.a
iolog_register_callback(io_log);
- irc_iofd = iosocket_connect("irc.nextirc.net", 6667, 0, NULL, io_callback);
- irc_iofd->parse_delimiter = 1;
- irc_iofd->delimiters[0] = '\n';
- irc_iofd->delimiters[1] = '\r';
+ irc_iofd = iosocket_connect("test.pk910.de", 443, 1, NULL, io_callback);
iohandler_run();
switch(event->type) {
case IOSOCKETEVENT_CONNECTED:
printf("[connect]\n");
+ iosocket_printf(event->socket, "GET / HTTP/1.1\r\n");
+ iosocket_printf(event->socket, "Host: test.pk910.de\r\n");
+ iosocket_printf(event->socket, "\r\n");
break;
case IOSOCKETEVENT_CLOSED:
printf("[disconnect]\n");
break;
case IOSOCKETEVENT_RECV:
- printf("[in] %s\n", event->data.recv_str);
+ {
+ struct IOSocketBuffer *recv_buf = event->data.recv_buf;
+ write(1, recv_buf->buffer, recv_buf->bufpos);
+ recv_buf->bufpos = 0;
+ printf("\n");
+ }
break;
default: