unsigned short port; /* the remote port */
int type; /* the type of this connection (tcp/udp/raw) */
+#ifdef USE_SSL
+ SSL *sslid; /* ssl handle for this client */
+#endif
+
Listener *listener; /* listener this client came in on (optional) */
SockEng *sockeng; /* socket engine for this client */
/*
* The listener structure provides all necessary details in order to build and maintain a listener
*/
+
+#define LISTEN_SSL 0x01
+
struct _listener {
myfd fdp; /* file descriptor abstraction */
unsigned short port; /* port of the descriptor */
--- /dev/null
+/* wrap_ssl.h
+ * external definitions of SSL wrapping functions
+ */
+
+#ifdef USE_SSL
+#ifndef WRAP_SSL_H
+#define WRAP_SSL_H
+
+#include "sockeng.h"
+
+extern int ssl_init(SockEng *s, char *certpath, char *keypath);
+extern int sslread(SSL *id, void *buf, int sz);
+extern int sslwrite(SSL *id, void *buf, int sz);
+extern int sslaccept(Client *c);
+extern void sslshut(SSL *id);
+
+#endif
+#endif
#include "sockeng.h"
#include "mfd.h"
+#include "wrap_ssl.h"
static int client_send(Client *c, char *msg, int len)
{
ebuf_delete(&c->recvQ, eBufLength(&c->recvQ));
ebuf_delete(&c->sendQ, eBufLength(&c->sendQ));
mfd_del(c->sockeng, &c->fdp);
+#ifdef USE_SSL
+ if(c->sslid)
+ sslshut(c->sslid);
+#endif
close(c->fdp.fd);
free(c);
return RET_OK;
static char readbuf[BUFSIZE];
int len, plen;
+#ifdef USE_SSL
+ if(c->sslid)
+ len = sslread(c->sslid, readbuf, sizeof(readbuf));
+ else
+ len = recv(c->fdp.fd, readbuf, sizeof(readbuf), 0);
+#else
len = recv(c->fdp.fd, readbuf, sizeof(readbuf), 0);
+#endif
if(len < 0) {
if(errno == EWOULDBLOCK || errno == EAGAIN)
return;
return;
}
num = ebuf_mapiov(&c->sendQ, v);
+#ifdef USE_SSL
+ /* FIXME: revisit this - maybe we should try to do mulitple sslwrite() calls here to flush buffers faster */
+ if(c->sslid)
+ ret = sslwrite(c->sslid, v->iov_base, v->iov_len);
+ else
+ ret = writev(c->fdp.fd, v, num);
+#else
ret = writev(c->fdp.fd, v, num);
+#endif
if(ret > 0)
ebuf_delete(&c->sendQ, ret);
if(!(eBufLength(&c->sendQ) > 0))
#include "sockeng.h"
#include "mfd.h"
+#include "wrap_ssl.h"
#include <unistd.h>
#include <fcntl.h>
static int listener_qopts(Listener *l, int opts)
{
+ l->flags = opts;
return RET_OK;
}
new->addr.type = TYPE_IPV6;
memcpy(&new->addr.ip, &addr.sin6_addr, sizeof(struct in6_addr));
new->port = ntohs(addr.sin6_port);
+#ifdef USE_SSL
+ if((l->flags & LISTEN_SSL) && sslaccept(new))
+ new->close(new); /* failed SSL negotiation, drop it */
+#endif
if(l->onconnect != NULL && (*l->onconnect)(new)) {
new->close(new);
continue;
new->addr.type = TYPE_IPV4;
memcpy(&new->addr.ip, &addr.sin_addr, sizeof(struct in_addr));
new->port = ntohs(addr.sin_port);
+#ifdef USE_SSL
+ if((l->flags & LISTEN_SSL) && sslaccept(new))
+ new->close(new); /* failed SSL negotation, drop it */
+#endif
if(l->onconnect != NULL && (*l->onconnect)(new)) {
new->close(new);
continue;
return call_ssl(CALL_SSLWRITE, id, buf, sz);
}
-int sslaccept(SSL *id)
+int sslaccept(Client *c)
{
- return call_ssl(CALL_SSLACCEPT, id, NULL, 0);
+ int ret;
+ SSL *id;
+
+ id = SSL_new(c->sockeng->sslctx);
+ if(!id)
+ return -1;
+ SSL_set_fd(id, c->fdp.fd);
+ ret = call_ssl(CALL_SSLACCEPT, id, NULL, 0);
+ if(ret) {
+ call_ssl(CALL_SSLSHUT, id, NULL, 0);
+ SSL_free(id);
+ return -1;
+ }
+ c->sslid = id;
+ return ret;
}
-int sslshut(SSL *id)
+void sslshut(SSL *id)
{
- return call_ssl(CALL_SSLSHUT, id, NULL, 0);
+ call_ssl(CALL_SSLSHUT, id, NULL, 0);
+ SSL_free(id);
}