nixio:
authorSteven Barth <steven@midlink.org>
Mon, 23 Feb 2009 17:21:14 +0000 (17:21 +0000)
committerSteven Barth <steven@midlink.org>
Mon, 23 Feb 2009 17:21:14 +0000 (17:21 +0000)
Reogranize TLS headers
Fix TLS receive buffer workaround for axTLS
Add support for flock()

libs/nixio/src/file.c
libs/nixio/src/nixio-tls.h [new file with mode: 0644]
libs/nixio/src/nixio.h
libs/nixio/src/tls-context.c
libs/nixio/src/tls-socket.c

index 3333e23..4c18eed 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/file.h>
 
 
 static int nixio_file(lua_State *L) {
@@ -155,6 +156,29 @@ static int nixio_file_flush(lua_State *L) {
        return nixio__pstatus(L, !fflush(f));
 }
 
+static int nixio_file_lock(lua_State *L) {
+       int fd = fileno(nixio__checkfile(L));
+
+       const int j = lua_gettop(L);
+       int flags = 0;
+       for (int i=2; i<=j; i++) {
+               const char *flag = luaL_checkstring(L, i);
+               if (!strcmp(flag, "sh")) {
+                       flags |= LOCK_SH;
+               } else if (!strcmp(flag, "ex")) {
+                       flags |= LOCK_EX;
+               } else if (!strcmp(flag, "un")) {
+                       flags |= LOCK_UN;
+               } else if (!strcmp(flag, "nb")) {
+                       flags |= LOCK_NB;
+               } else {
+                       return luaL_argerror(L, i, "supported values: sh, ex, un, nb");
+               }
+       }
+
+       return nixio__pstatus(L, flock(fd, flags));
+}
+
 static int nixio_file_close(lua_State *L) {
        FILE **fpp = (FILE**)luaL_checkudata(L, 1, NIXIO_FILE_META);
        luaL_argcheck(L, *fpp, 1, "invalid file object");
@@ -187,6 +211,7 @@ static const luaL_reg M[] = {
        {"tell",                nixio_file_tell},
        {"seek",                nixio_file_seek},
        {"flush",               nixio_file_flush},
+       {"lock",                nixio_file_lock},
        {"close",               nixio_file_close},
        {"__gc",                nixio_file__gc},
        {"__tostring",  nixio_file__tostring},
diff --git a/libs/nixio/src/nixio-tls.h b/libs/nixio/src/nixio-tls.h
new file mode 100644 (file)
index 0000000..13b400e
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef NIXIO_TLS_H_
+#define NIXIO_TLS_H_
+
+#include "nixio.h"
+
+#ifndef WITHOUT_OPENSSL
+#include <openssl/ssl.h>
+#endif
+
+#define NIXIO_TLS_CTX_META "nixio.tls.ctx"
+#define NIXIO_TLS_SOCK_META "nixio.tls.sock"
+
+typedef struct nixio_tls_socket {
+       SSL             *socket;
+#ifdef WITH_AXTLS
+       size_t  pbufsiz;
+       char    *pbufpos;
+       char    *pbuffer;
+#endif
+} nixio_tls_sock;
+
+#endif /* NIXIO_TLS_H_ */
index 5a491c5..1b35e2e 100644 (file)
@@ -3,8 +3,6 @@
 
 #define NIXIO_META "nixio.socket"
 #define NIXIO_FILE_META "nixio.file"
-#define NIXIO_TLS_CTX_META "nixio.tls.ctx"
-#define NIXIO_TLS_SOCK_META "nixio.tls.sock"
 #define NIXIO_BUFFERSIZE 8096
 #define _FILE_OFFSET_BITS 64
 
 #include <lualib.h>
 #include <lauxlib.h>
 
-struct nixio_socket {
+typedef struct nixio_socket {
        int fd;
        int domain;
        int type;
        int protocol;
-};
-
-typedef struct nixio_socket nixio_sock;
+} nixio_sock;
 
 int nixio__perror(lua_State *L);
 int nixio__pstatus(lua_State *L, int condition);
index 723f8a8..ff3feeb 100644 (file)
  *  limitations under the License.
  */
 
-#include "nixio.h"
-#include "string.h"
-
-#ifndef WITHOUT_OPENSSL
-#include <openssl/ssl.h>
-#endif
+#include "nixio-tls.h"
+#include <string.h>
 
 static SSL_CTX* nixio__checktlsctx(lua_State *L) {
        SSL_CTX **ctx = (SSL_CTX **)luaL_checkudata(L, 1, NIXIO_TLS_CTX_META);
@@ -78,21 +74,22 @@ static int nixio_tls_ctx_create(lua_State *L) {
        SSL_CTX *ctx = nixio__checktlsctx(L);
        int fd = nixio__checkfd(L, 2);
 
-       SSL **sock = lua_newuserdata(L, sizeof(SSL *));
+       nixio_tls_sock *sock = lua_newuserdata(L, sizeof(nixio_tls_sock));
        if (!sock) {
                return luaL_error(L, "out of memory");
        }
+       memset(sock, 0, sizeof(nixio_tls_sock));
 
        /* create userdata */
        luaL_getmetatable(L, NIXIO_TLS_SOCK_META);
        lua_setmetatable(L, -2);
 
-       *sock = SSL_new(ctx);
-       if (!(*sock)) {
+       sock->socket = SSL_new(ctx);
+       if (!sock->socket) {
                return nixio__tls_perror(L, 0);
        }
 
-       if (SSL_set_fd(*sock, fd) != 1) {
+       if (SSL_set_fd(sock->socket, fd) != 1) {
                return nixio__tls_perror(L, 0);
        }
 
index a305518..b26d140 100644 (file)
  *  limitations under the License.
  */
 
-#include "nixio.h"
-#include "string.h"
-
-#ifndef WITHOUT_OPENSSL
-#include <openssl/ssl.h>
-#endif
+#include "nixio-tls.h"
+#include <string.h>
+#include <stdlib.h>
 
 static int nixio__tls_sock_perror(lua_State *L, SSL *sock, int code) {
        lua_pushnil(L);
@@ -40,9 +37,9 @@ static int nixio__tls_sock_pstatus(lua_State *L, SSL *sock, int code) {
 }
 
 static SSL* nixio__checktlssock(lua_State *L) {
-       SSL **sock = (SSL **)luaL_checkudata(L, 1, NIXIO_TLS_SOCK_META);
-       luaL_argcheck(L, *sock, 1, "invalid context");
-       return *sock;
+       nixio_tls_sock *sock = luaL_checkudata(L, 1, NIXIO_TLS_SOCK_META);
+       luaL_argcheck(L, sock->socket, 1, "invalid context");
+       return sock->socket;
 }
 
 static int nixio_tls_sock_recv(lua_State *L) {
@@ -53,7 +50,9 @@ static int nixio_tls_sock_recv(lua_State *L) {
 
        /* We limit the readsize to NIXIO_BUFFERSIZE */
        req = (req > NIXIO_BUFFERSIZE) ? NIXIO_BUFFERSIZE : req;
+
 #ifndef WITH_AXTLS
+
        char buffer[NIXIO_BUFFERSIZE];
        int readc = SSL_read(sock, buffer, req);
 
@@ -63,69 +62,85 @@ static int nixio_tls_sock_recv(lua_State *L) {
                lua_pushlstring(L, buffer, readc);
                return 1;
        }
+
 #else
+
        if (!req) {
                lua_pushliteral(L, "");
                return 1;
        }
 
-       /* AXTLS doesn't handle buffering for us, so we have to hack around*/
-       int buflen = 0;
-       lua_getmetatable(L, 1);
-       lua_getfield(L, -1, "_axbuffer");
-
-       if (lua_isstring(L, -1)) {
-               buflen = lua_objlen(L, -1);
-       }
+       nixio_tls_sock *t = lua_touserdata(L, 1);
 
-       if (req < buflen) {
-               const char *axbuf = lua_tostring(L, -1);
-               lua_pushlstring(L, axbuf, req);
-               lua_pushlstring(L, axbuf + req, buflen - req);
-               lua_setfield(L, -4, "_axbuffer");
+       /* AXTLS doesn't handle buffering for us, so we have to hack around*/
+       if (req < t->pbufsiz) {
+               lua_pushlstring(L, t->pbufpos, req);
+               t->pbufpos += req;
+               t->pbufsiz -= req;
                return 1;
        } else {
-               if (!lua_isstring(L, -1)) {
-                       lua_pop(L, 1);
-                       lua_pushliteral(L, "");
-               }
-
                char *axbuf;
                int axread;
 
                /* while handshake pending */
                while ((axread = ssl_read(sock, (uint8_t**)&axbuf)) == SSL_OK);
 
+               if (t->pbufsiz) {
+                       lua_pushlstring(L, t->pbufpos, t->pbufsiz);
+               }
+
                if (axread < 0) {
                        /* There is an error */
+                       free(t->pbuffer);
+                       t->pbuffer = t->pbufpos = NULL;
+                       t->pbufsiz = 0;
 
                        if (axread != SSL_ERROR_CONN_LOST) {
-                               lua_pushliteral(L, "");
-                               lua_setfield(L, -3, "_axbuffer");
                                return nixio__tls_sock_perror(L, sock, axread);
                        } else {
-                               lua_pushliteral(L, "");
+                               if (!t->pbufsiz) {
+                                       lua_pushliteral(L, "");
+                               }
                        }
                } else {
-                       int stillwant = req - buflen;
+                       int stillwant = req - t->pbufsiz;
                        if (stillwant < axread) {
                                /* we got more data than we need */
                                lua_pushlstring(L, axbuf, stillwant);
-                               lua_concat(L, 2);
+                               if(t->pbufsiz) {
+                                       lua_concat(L, 2);
+                               }
 
                                /* remaining data goes into the buffer */
-                               lua_pushlstring(L, axbuf + stillwant, axread - stillwant);
+                               t->pbufpos = t->pbuffer;
+                               t->pbufsiz = axread - stillwant;
+                               t->pbuffer = realloc(t->pbuffer, t->pbufsiz);
+                               if (!t->pbuffer) {
+                                       free(t->pbufpos);
+                                       t->pbufpos = NULL;
+                                       t->pbufsiz = 0;
+                                       return luaL_error(L, "out of memory");
+                               }
+
+                               t->pbufpos = t->pbuffer;
+                               memcpy(t->pbufpos, axbuf + stillwant, t->pbufsiz);
                        } else {
                                lua_pushlstring(L, axbuf, axread);
-                               lua_concat(L, 2);
-                               lua_pushliteral(L, "");
+                               if(t->pbufsiz) {
+                                       lua_concat(L, 2);
+                               }
+
+                               /* free buffer */
+                               free(t->pbuffer);
+                               t->pbuffer = t->pbufpos = NULL;
+                               t->pbufsiz = 0;
                        }
                }
-               lua_setfield(L, -3, "_axbuffer");
                return 1;
        }
 
-#endif
+#endif /* WITH_AXTLS */
+
 }
 
 static int nixio_tls_sock_send(lua_State *L) {
@@ -158,10 +173,13 @@ static int nixio_tls_sock_shutdown(lua_State *L) {
 }
 
 static int nixio_tls_sock__gc(lua_State *L) {
-       SSL **sock = (SSL **)luaL_checkudata(L, 1, NIXIO_TLS_SOCK_META);
-       if (*sock) {
-               SSL_free(*sock);
-               *sock = NULL;
+       nixio_tls_sock *sock = luaL_checkudata(L, 1, NIXIO_TLS_SOCK_META);
+       if (sock->socket) {
+               SSL_free(sock->socket);
+               sock->socket = NULL;
+#ifdef WITH_AXTLS
+               free(sock->pbuffer);
+#endif
        }
        return 0;
 }