Preliminary IPv6 support for v2.1

This commit is contained in:
Diego Nehab 2012-04-11 13:21:25 -07:00 committed by Sam Roberts
parent 3a8ba90dfb
commit 2778766d67
40 changed files with 432 additions and 52 deletions

View File

@ -2,7 +2,7 @@
-- Little program to convert to and from Base64 -- Little program to convert to and from Base64
-- LuaSocket sample files -- LuaSocket sample files
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: b64.lua,v 1.8 2004/06/16 04:28:21 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local mime = require("mime") local mime = require("mime")

View File

@ -2,7 +2,7 @@
-- Little program to download DICT word definitions -- Little program to download DICT word definitions
-- LuaSocket sample files -- LuaSocket sample files
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: dict.lua,v 1.22 2005/11/22 08:33:29 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@
-- Little program to adjust end of line markers. -- Little program to adjust end of line markers.
-- LuaSocket sample files -- LuaSocket sample files
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: eol.lua,v 1.8 2005/11/22 08:33:29 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local mime = require("mime") local mime = require("mime")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")

View File

@ -2,7 +2,7 @@
-- Little program to download files from URLs -- Little program to download files from URLs
-- LuaSocket sample files -- LuaSocket sample files
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: get.lua,v 1.25 2007/03/12 04:08:40 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local socket = require("socket") local socket = require("socket")
local http = require("socket.http") local http = require("socket.http")

View File

@ -3,7 +3,7 @@
-- LuaSocket toolkit. -- LuaSocket toolkit.
-- Author: David Burgess -- Author: David Burgess
-- Modified by Diego Nehab, but David is in charge -- Modified by Diego Nehab, but David is in charge
-- RCS ID: $Id$ -- RCS ID: $Id: lp.lua,v 1.14 2005/11/21 07:04:44 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
--[[ --[[
if you have any questions: RFC 1179 if you have any questions: RFC 1179

View File

@ -2,7 +2,7 @@
-- Little program to convert to and from Quoted-Printable -- Little program to convert to and from Quoted-Printable
-- LuaSocket sample files -- LuaSocket sample files
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: qp.lua,v 1.5 2004/06/17 21:46:22 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local mime = require("mime") local mime = require("mime")

View File

@ -2,7 +2,7 @@
-- TFTP support for the Lua language -- TFTP support for the Lua language
-- LuaSocket toolkit. -- LuaSocket toolkit.
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: tftp.lua,v 1.16 2005/11/22 08:33:29 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@
-- UDP sample: daytime protocol client -- UDP sample: daytime protocol client
-- LuaSocket sample files -- LuaSocket sample files
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: daytimeclnt.lua,v 1.11 2004/06/21 06:07:57 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local socket = require"socket" local socket = require"socket"
host = host or "127.0.0.1" host = host or "127.0.0.1"

View File

@ -2,7 +2,7 @@
-- UDP sample: echo protocol client -- UDP sample: echo protocol client
-- LuaSocket sample files -- LuaSocket sample files
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: echoclnt.lua,v 1.10 2005/01/02 22:44:00 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local socket = require("socket") local socket = require("socket")
host = host or "localhost" host = host or "localhost"

View File

@ -2,7 +2,7 @@
-- UDP sample: echo protocol server -- UDP sample: echo protocol server
-- LuaSocket sample files -- LuaSocket sample files
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: echosrvr.lua,v 1.12 2005/11/22 08:33:29 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local socket = require("socket") local socket = require("socket")
host = host or "127.0.0.1" host = host or "127.0.0.1"

View File

@ -2,7 +2,7 @@
-- TCP sample: Little program to dump lines received at a given port -- TCP sample: Little program to dump lines received at a given port
-- LuaSocket sample files -- LuaSocket sample files
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: listener.lua,v 1.11 2005/01/02 22:44:00 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local socket = require("socket") local socket = require("socket")
host = host or "*" host = host or "*"

18
samples/mclisten.lua Normal file
View File

@ -0,0 +1,18 @@
local socket = require"socket"
local group = "225.0.0.37"
local port = 12345
local c = assert(socket.udp())
print(assert(c:setoption("reuseport", true)))
print(assert(c:setsockname("*", port)))
--print("loop:", c:getoption("ip-multicast-loop"))
--print(assert(c:setoption("ip-multicast-loop", false)))
--print("loop:", c:getoption("ip-multicast-loop"))
--print("if:", c:getoption("ip-multicast-if"))
--print(assert(c:setoption("ip-multicast-if", "127.0.0.1")))
--print("if:", c:getoption("ip-multicast-if"))
--print(assert(c:setoption("ip-multicast-if", "10.0.1.4")))
--print("if:", c:getoption("ip-multicast-if"))
print(assert(c:setoption("ip-add-membership", {multiaddr = group, interface = "*"})))
while 1 do
print(c:receivefrom())
end

20
samples/mcsend.lua Normal file
View File

@ -0,0 +1,20 @@
local socket = require"socket"
local group = "225.0.0.37"
local port = 12345
local c = assert(socket.udp())
--print(assert(c:setoption("reuseport", true)))
--print(assert(c:setsockname("*", port)))
--print(assert(c:setoption("ip-multicast-loop", false)))
--print(assert(c:setoption("ip-multicast-ttl", 4)))
--print(assert(c:setoption("ip-multicast-if", "10.0.1.3")))
--print(assert(c:setoption("ip-add-membership", {multiaddr = group, interface = "*"})))
local i = 0
while 1 do
local message = string.format("hello all %d!", i)
assert(c:sendto(message, group, port))
print("sent " .. message)
socket.sleep(1)
c:settimeout(0.5)
print(c:receivefrom())
i = i + 1
end

View File

@ -2,7 +2,7 @@
-- TCP sample: Little program to send text lines to a given host/port -- TCP sample: Little program to send text lines to a given host/port
-- LuaSocket sample files -- LuaSocket sample files
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: talker.lua,v 1.9 2005/01/02 22:44:00 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local socket = require("socket") local socket = require("socket")
host = host or "localhost" host = host or "localhost"

View File

@ -2,7 +2,7 @@
-- Select sample: simple text line server -- Select sample: simple text line server
-- LuaSocket sample files. -- LuaSocket sample files.
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: tinyirc.lua,v 1.14 2005/11/22 08:33:29 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local socket = require("socket") local socket = require("socket")
host = host or "*" host = host or "*"

View File

@ -2,7 +2,7 @@
* Auxiliar routines for class hierarchy manipulation * Auxiliar routines for class hierarchy manipulation
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: auxiliar.c,v 1.14 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>

View File

@ -2,7 +2,7 @@
* Input/Output interface for Lua programs * Input/Output interface for Lua programs
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: buffer.c,v 1.29 2009/05/27 09:31:35 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include "lua.h" #include "lua.h"
#include "lauxlib.h" #include "lauxlib.h"

View File

@ -2,7 +2,7 @@
* Simple exception support * Simple exception support
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: except.c,v 1.8 2005/09/29 06:11:41 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <stdio.h> #include <stdio.h>

View File

@ -2,7 +2,7 @@
-- FTP support for the Lua language -- FTP support for the Lua language
-- LuaSocket toolkit. -- LuaSocket toolkit.
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: ftp.lua,v 1.45 2007/07/11 19:25:47 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------

100
src/headers.lua Normal file
View File

@ -0,0 +1,100 @@
-----------------------------------------------------------------------------
-- Canonic header field capitalization
-- LuaSocket toolkit.
-- Author: Diego Nehab
-- RCS ID: $Id$
-----------------------------------------------------------------------------
module("socket.headers")
canonic = {
["accept"] = "Accept",
["accept-charset"] = "Accept-Charset",
["accept-encoding"] = "Accept-Encoding",
["accept-language"] = "Accept-Language",
["accept-ranges"] = "Accept-Ranges",
["action"] = "Action",
["alternate-recipient"] = "Alternate-Recipient",
["age"] = "Age",
["allow"] = "Allow",
["arrival-date"] = "Arrival-Date",
["authorization"] = "Authorization",
["bcc"] = "Bcc",
["cache-control"] = "Cache-Control",
["cc"] = "Cc",
["comments"] = "Comments",
["connection"] = "Connection",
["content-description"] = "Content-Description",
["content-disposition"] = "Content-Disposition",
["content-encoding"] = "Content-Encoding",
["content-id"] = "Content-ID",
["content-language"] = "Content-Language",
["content-length"] = "Content-Length",
["content-location"] = "Content-Location",
["content-md5"] = "Content-MD5",
["content-range"] = "Content-Range",
["content-transfer-encoding"] = "Content-Transfer-Encoding",
["content-type"] = "Content-Type",
["date"] = "Date",
["diagnostic-code"] = "Diagnostic-Code",
["dsn-gateway"] = "DSN-Gateway",
["etag"] = "ETag",
["expect"] = "Expect",
["expires"] = "Expires",
["final-log-id"] = "Final-Log-ID",
["final-recipient"] = "Final-Recipient",
["from"] = "From",
["host"] = "Host",
["if-match"] = "If-Match",
["if-modified-since"] = "If-Modified-Since",
["if-none-match"] = "If-None-Match",
["if-range"] = "If-Range",
["if-unmodified-since"] = "If-Unmodified-Since",
["in-reply-to"] = "In-Reply-To",
["keywords"] = "Keywords",
["last-attempt-date"] = "Last-Attempt-Date",
["last-modified"] = "Last-Modified",
["location"] = "Location",
["max-forwards"] = "Max-Forwards",
["message-id"] = "Message-ID",
["mime-version"] = "MIME-Version",
["original-envelope-id"] = "Original-Envelope-ID",
["original-recipient"] = "Original-Recipient",
["pragma"] = "Pragma",
["proxy-authenticate"] = "Proxy-Authenticate",
["proxy-authorization"] = "Proxy-Authorization",
["range"] = "Range",
["received"] = "Received",
["received-from-mta"] = "Received-From-MTA",
["references"] = "References",
["referer"] = "Referer",
["remote-mta"] = "Remote-MTA",
["reply-to"] = "Reply-To",
["reporting-mta"] = "Reporting-MTA",
["resent-bcc"] = "Resent-Bcc",
["resent-cc"] = "Resent-Cc",
["resent-date"] = "Resent-Date",
["resent-from"] = "Resent-From",
["resent-message-id"] = "Resent-Message-ID",
["resent-reply-to"] = "Resent-Reply-To",
["resent-sender"] = "Resent-Sender",
["resent-to"] = "Resent-To",
["retry-after"] = "Retry-After",
["return-path"] = "Return-Path",
["sender"] = "Sender",
["server"] = "Server",
["smtp-remote-recipient"] = "SMTP-Remote-Recipient",
["status"] = "Status",
["subject"] = "Subject",
["te"] = "TE",
["to"] = "To",
["trailer"] = "Trailer",
["transfer-encoding"] = "Transfer-Encoding",
["upgrade"] = "Upgrade",
["user-agent"] = "User-Agent",
["vary"] = "Vary",
["via"] = "Via",
["warning"] = "Warning",
["will-retry-until"] = "Will-Retry-Until",
["www-authenticate"] = "WWW-Authenticate",
["x-mailer"] = "X-Mailer",
}

View File

@ -2,7 +2,7 @@
-- HTTP/1.1 client support for the Lua language. -- HTTP/1.1 client support for the Lua language.
-- LuaSocket toolkit. -- LuaSocket toolkit.
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: http.lua,v 1.72 2009/05/27 09:31:35 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@
* Internet domain functions * Internet domain functions
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: inet.c,v 1.28 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -16,14 +16,16 @@
* Internal function prototypes. * Internal function prototypes.
\*=========================================================================*/ \*=========================================================================*/
static int inet_global_toip(lua_State *L); static int inet_global_toip(lua_State *L);
static int inet_global_toip6(lua_State *L);
static int inet_global_tohostname(lua_State *L); static int inet_global_tohostname(lua_State *L);
static void inet_pushresolved(lua_State *L, struct hostent *hp); static void inet_pushresolved(lua_State *L, struct hostent *hp);
static int inet_global_gethostname(lua_State *L); static int inet_global_gethostname(lua_State *L);
/* DNS functions */ /* DNS functions */
static luaL_reg func[] = { static luaL_reg func[] = {
{ "toip", inet_global_toip }, { "toip", inet_global_toip},
{ "tohostname", inet_global_tohostname }, { "toip6", inet_global_toip6},
{ "tohostname", inet_global_tohostname},
{ "gethostname", inet_global_gethostname}, { "gethostname", inet_global_gethostname},
{ NULL, NULL} { NULL, NULL}
}; };
@ -95,6 +97,50 @@ static int inet_global_toip(lua_State *L)
return 2; return 2;
} }
static int inet_global_toip6(lua_State *L)
{
const char *hostname = luaL_checkstring(L, 1);
struct addrinfo *iterator = NULL, *resolved = NULL;
struct addrinfo hints;
int i = 1, ret = 0;
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = PF_UNSPEC;
ret = getaddrinfo(hostname, NULL, &hints, &resolved);
if (ret != 0) {
lua_pushnil(L);
lua_pushstring(L, "getaddrinfo returned error");
return 2;
}
lua_newtable(L);
for (iterator = resolved; iterator; iterator = iterator->ai_next) {
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
getnameinfo(iterator->ai_addr, iterator->ai_addrlen, hbuf, sizeof(hbuf),
sbuf, 0, NI_NUMERICHOST);
lua_pushnumber(L, i);
lua_newtable(L);
switch (iterator->ai_family) {
case AF_INET:
lua_pushliteral(L, "family");
lua_pushliteral(L, "inet");
lua_settable(L, -3);
break;
case AF_INET6:
lua_pushliteral(L, "family");
lua_pushliteral(L, "inet6");
lua_settable(L, -3);
break;;
}
lua_pushliteral(L, "addr");
lua_pushstring(L, hbuf);
lua_settable(L, -3);
lua_settable(L, -3);
i++;
}
freeaddrinfo(resolved);
return 1;
}
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Gets the host name * Gets the host name

View File

@ -2,7 +2,7 @@
* Input/Output abstraction * Input/Output abstraction
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: io.c,v 1.6 2005/09/29 06:11:41 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include "io.h" #include "io.h"

View File

@ -2,7 +2,7 @@
-- LTN12 - Filters, sources, sinks and pumps. -- LTN12 - Filters, sources, sinks and pumps.
-- LuaSocket toolkit. -- LuaSocket toolkit.
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: ltn12.lua,v 1.31 2006/04/03 04:45:42 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------

View File

@ -11,8 +11,8 @@
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Current socket library version * Current socket library version
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
#define LUASOCKET_VERSION "LuaSocket 2.0.3" #define LUASOCKET_VERSION "LuaSocket 2.1.0"
#define LUASOCKET_COPYRIGHT "Copyright (C) 1999-2009 Diego Nehab" #define LUASOCKET_COPYRIGHT "Copyright (C) 1999-2011 Diego Nehab"
#define LUASOCKET_AUTHORS "Diego Nehab" #define LUASOCKET_AUTHORS "Diego Nehab"
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\

View File

@ -2,7 +2,7 @@
* MIME support functions * MIME support functions
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: mime.c,v 1.29 2009/05/27 09:31:35 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <string.h> #include <string.h>

View File

@ -2,7 +2,7 @@
-- MIME support for the Lua language. -- MIME support for the Lua language.
-- Author: Diego Nehab -- Author: Diego Nehab
-- Conforming to RFCs 2045-2049 -- Conforming to RFCs 2045-2049
-- RCS ID: $Id$ -- RCS ID: $Id: mime.lua,v 1.29 2007/06/11 23:44:54 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@
* Common option interface * Common option interface
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: options.c,v 1.7 2009/05/27 09:31:35 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <string.h> #include <string.h>

View File

@ -2,7 +2,7 @@
* Select implementation * Select implementation
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: select.c,v 1.23 2009/05/27 09:31:35 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <string.h> #include <string.h>
@ -95,8 +95,10 @@ static t_socket getfd(lua_State *L) {
if (!lua_isnil(L, -1)) { if (!lua_isnil(L, -1)) {
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
lua_call(L, 1, 1); lua_call(L, 1, 1);
if (lua_isnumber(L, -1)) if (lua_isnumber(L, -1)) {
fd = (t_socket) lua_tonumber(L, -1); double numfd = lua_tonumber(L, -1);
fd = (numfd >= 0.0)? (t_socket) numfd: SOCKET_INVALID;
}
} }
lua_pop(L, 1); lua_pop(L, 1);
return fd; return fd;
@ -134,8 +136,13 @@ static void collect_fd(lua_State *L, int tab, int itab,
fd = getfd(L); fd = getfd(L);
if (fd != SOCKET_INVALID) { if (fd != SOCKET_INVALID) {
/* make sure we don't overflow the fd_set */ /* make sure we don't overflow the fd_set */
#ifdef _WIN32
if (n >= FD_SETSIZE) if (n >= FD_SETSIZE)
luaL_argerror(L, tab, "too many sockets"); luaL_argerror(L, tab, "too many sockets");
#else
if (fd >= FD_SETSIZE)
luaL_argerror(L, tab, "descriptor too large for set size");
#endif
FD_SET(fd, set); FD_SET(fd, set);
n++; n++;
/* keep track of the largest descriptor so far */ /* keep track of the largest descriptor so far */

View File

@ -2,7 +2,7 @@
-- SMTP client support for the Lua language. -- SMTP client support for the Lua language.
-- LuaSocket toolkit. -- LuaSocket toolkit.
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: smtp.lua,v 1.47 2009/05/27 09:31:35 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------

View File

@ -59,6 +59,7 @@ int socket_accept(p_socket ps, p_socket pa, SA *addr,
socklen_t *addr_len, p_timeout tm); socklen_t *addr_len, p_timeout tm);
const char *socket_hoststrerror(int err); const char *socket_hoststrerror(int err);
const char *socket_gaistrerror(int err);
const char *socket_strerror(int err); const char *socket_strerror(int err);
/* these are perfect to use with the io abstraction module /* these are perfect to use with the io abstraction module

View File

@ -1,7 +1,7 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- LuaSocket helper module -- LuaSocket helper module
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: socket.lua,v 1.22 2005/11/22 08:33:29 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------

181
src/tcp.c
View File

@ -2,7 +2,7 @@
* TCP object * TCP object
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: tcp.c,v 1.42 2009/05/27 09:31:35 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <string.h> #include <string.h>
@ -19,6 +19,8 @@
* Internal function prototypes * Internal function prototypes
\*=========================================================================*/ \*=========================================================================*/
static int global_create(lua_State *L); static int global_create(lua_State *L);
static int global_connect6(lua_State *L);
static int global_bind6(lua_State *L);
static int meth_connect(lua_State *L); static int meth_connect(lua_State *L);
static int meth_listen(lua_State *L); static int meth_listen(lua_State *L);
static int meth_bind(lua_State *L); static int meth_bind(lua_State *L);
@ -75,6 +77,8 @@ static t_opt optset[] = {
/* functions in library namespace */ /* functions in library namespace */
static luaL_reg func[] = { static luaL_reg func[] = {
{"tcp", global_create}, {"tcp", global_create},
{"connect6", global_connect6},
{"bind6", global_bind6},
{NULL, NULL} {NULL, NULL}
}; };
@ -208,6 +212,7 @@ static int meth_bind(lua_State *L)
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
static int meth_connect(lua_State *L) static int meth_connect(lua_State *L)
{ {
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
const char *address = luaL_checkstring(L, 2); const char *address = luaL_checkstring(L, 2);
unsigned short port = (unsigned short) luaL_checknumber(L, 3); unsigned short port = (unsigned short) luaL_checknumber(L, 3);
@ -220,7 +225,6 @@ static int meth_connect(lua_State *L)
lua_pushstring(L, err); lua_pushstring(L, err);
return 2; return 2;
} }
/* turn master object into a client object */
lua_pushnumber(L, 1); lua_pushnumber(L, 1);
return 1; return 1;
} }
@ -313,8 +317,7 @@ static int meth_settimeout(lua_State *L)
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Creates a master tcp object * Creates a master tcp object
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
static int global_create(lua_State *L) static int global_create(lua_State *L) {
{
t_socket sock; t_socket sock;
const char *err = inet_trycreate(&sock, SOCK_STREAM); const char *err = inet_trycreate(&sock, SOCK_STREAM);
/* try to allocate a system socket */ /* try to allocate a system socket */
@ -337,3 +340,173 @@ static int global_create(lua_State *L)
return 2; return 2;
} }
} }
static const char *trybind6(const char *localaddr, const char *localserv,
struct addrinfo *bindhints, p_tcp tcp) {
struct addrinfo *iterator = NULL, *resolved = NULL;
const char *err = NULL;
/* translate luasocket special values to C */
if (strcmp(localaddr, "*") == 0) localaddr = NULL;
if (!localserv) localserv = "0";
/* try resolving */
err = socket_gaistrerror(getaddrinfo(localaddr, localserv,
bindhints, &resolved));
if (err) {
if (resolved) freeaddrinfo(resolved);
return err;
}
/* iterate over resolved addresses until one is good */
for (iterator = resolved; iterator; iterator = iterator->ai_next) {
/* create a new socket each time because parameters
* may have changed */
const char *err = socket_strerror(socket_create(&tcp->sock,
iterator->ai_family, iterator->ai_socktype,
iterator->ai_protocol));
/* if failed to create socket, bail out */
if (err != NULL) {
freeaddrinfo(resolved);
return err;
}
/* all sockets are set as non-blocking initially */
socket_setnonblocking(&tcp->sock);
/* try binding to local address */
err = socket_strerror(socket_bind(&tcp->sock,
(SA *) iterator->ai_addr,
iterator->ai_addrlen));
/* if faiiled, we try the next one */
if (err != NULL) socket_destroy(&tcp->sock);
/* if success, we abort loop */
else break;
}
/* at this point, if err is not set, se succeeded */
if (err == NULL) {
/* save family of chosen local address */
bindhints->ai_family = iterator->ai_family;
}
/* cleanup and return error */
freeaddrinfo(resolved);
return err;
}
static int global_bind6(lua_State *L) {
const char *localaddr = luaL_checkstring(L, 1);
const char *localserv = luaL_checkstring(L, 2);
int backlog = luaL_checkint(L, 3);
p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
struct addrinfo bindhints;
const char *err = NULL;
/* initialize tcp structure */
io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
(p_error) socket_ioerror, &tcp->sock);
timeout_init(&tcp->tm, -1, -1);
buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
tcp->sock = SOCKET_INVALID;
/* try binding to local address */
memset(&bindhints, 0, sizeof(bindhints));
bindhints.ai_socktype = SOCK_STREAM;
bindhints.ai_family = PF_UNSPEC;
bindhints.ai_flags = AI_PASSIVE;
err = trybind6(localaddr, localserv, &bindhints, tcp);
if (err == NULL) {
/* all server sockets initially with reuseaddr set */
int val = 1;
setsockopt(tcp->sock, SOL_SOCKET, SO_REUSEADDR,
(char *) &val, sizeof(val));
/* set the backlog and listen */
err = socket_strerror(socket_listen(&tcp->sock, backlog));
if (err) {
socket_destroy(&tcp->sock);
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
auxiliar_setclass(L, "tcp{server}", -1);
return 1;
} else {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
}
static const char *tryconnect6(const char *remoteaddr, const char *remoteserv,
struct addrinfo *connecthints, p_tcp tcp) {
struct addrinfo *iterator = NULL, *resolved = NULL;
const char *err = NULL;
/* try resolving */
err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv,
connecthints, &resolved));
if (err != NULL) {
if (resolved) freeaddrinfo(resolved);
return err;
}
/* iterate over all returned addresses trying to connect */
for (iterator = resolved; iterator; iterator = iterator->ai_next) {
p_timeout tm = timeout_markstart(&tcp->tm);
/* create new socket if one wasn't created by the bind stage */
if (tcp->sock == SOCKET_INVALID) {
const char *err = socket_strerror(socket_create(&tcp->sock,
iterator->ai_family, iterator->ai_socktype,
iterator->ai_protocol));
if (err != NULL) {
freeaddrinfo(resolved);
return err;
}
/* all sockets initially non-blocking */
socket_setnonblocking(&tcp->sock);
}
/* finally try connecting to remote address */
err = socket_strerror(socket_connect(&tcp->sock,
(SA *) iterator->ai_addr,
iterator->ai_addrlen, tm));
/* if success, break out of loop */
if (err == NULL) break;
}
freeaddrinfo(resolved);
/* here, if err is set, we failed */
return err;
}
static int global_connect6(lua_State *L) {
const char *remoteaddr = luaL_checkstring(L, 1);
const char *remoteserv = luaL_checkstring(L, 2);
const char *localaddr = luaL_optstring(L, 3, NULL);
const char *localserv = luaL_optstring(L, 4, "0");
p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
struct addrinfo bindhints, connecthints;
const char *err = NULL;
/* initialize tcp structure */
io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
(p_error) socket_ioerror, &tcp->sock);
timeout_init(&tcp->tm, -1, -1);
buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
tcp->sock = SOCKET_INVALID;
/* allow user to pick local address and port */
memset(&bindhints, 0, sizeof(bindhints));
bindhints.ai_socktype = SOCK_STREAM;
bindhints.ai_family = PF_UNSPEC;
bindhints.ai_flags = AI_PASSIVE;
if (localaddr) {
err = trybind6(localaddr, localserv, &bindhints, tcp);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
}
/* try to connect to remote address and port */
memset(&connecthints, 0, sizeof(connecthints));
connecthints.ai_socktype = SOCK_STREAM;
/* make sure we try to connect only to the same family */
connecthints.ai_family = bindhints.ai_family;
err = tryconnect6(remoteaddr, remoteserv, &connecthints, tcp);
if (err) {
socket_destroy(&tcp->sock);
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
auxiliar_setclass(L, "tcp{client}", -1);
return 1;
}

View File

@ -2,7 +2,7 @@
* Timeout management functions * Timeout management functions
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: timeout.c,v 1.31 2009/05/27 09:31:35 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <stdio.h> #include <stdio.h>
#include <limits.h> #include <limits.h>

View File

@ -2,7 +2,7 @@
-- Unified SMTP/FTP subsystem -- Unified SMTP/FTP subsystem
-- LuaSocket toolkit. -- LuaSocket toolkit.
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: tp.lua,v 1.23 2009/05/27 09:31:35 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@
* UDP object * UDP object
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: udp.c,v 1.30 2009/05/27 09:31:35 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <string.h> #include <string.h>

View File

@ -2,7 +2,7 @@
* Unix domain socket * Unix domain socket
* LuaSocket toolkit * LuaSocket toolkit
* *
* RCS ID: $Id$ * RCS ID: $Id: unix.c,v 1.14 2009/05/27 09:31:35 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <string.h> #include <string.h>

View File

@ -2,7 +2,7 @@
-- URI parsing, composition and relative URL resolution -- URI parsing, composition and relative URL resolution
-- LuaSocket toolkit. -- LuaSocket toolkit.
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id: url.lua,v 1.38 2006/04/03 04:45:42 diego Exp $
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
@ -195,13 +195,7 @@ function build(parsed)
end end
if userinfo then authority = userinfo .. "@" .. authority end if userinfo then authority = userinfo .. "@" .. authority end
end end
if authority then if authority then url = "//" .. authority .. url end
if string.sub(url, 1, 1) == "/" then
url = "//" .. authority .. url
else
url = "//" .. authority .. "/" .. url
end
end
if parsed.scheme then url = parsed.scheme .. ":" .. url end if parsed.scheme then url = parsed.scheme .. ":" .. url end
if parsed.fragment then url = url .. "#" .. parsed.fragment end if parsed.fragment then url = url .. "#" .. parsed.fragment end
-- url = string.gsub(url, "%s", "") -- url = string.gsub(url, "%s", "")
@ -217,8 +211,8 @@ end
-- corresponding absolute url -- corresponding absolute url
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function absolute(base_url, relative_url) function absolute(base_url, relative_url)
local base_parsed = base_url
if base.type(base_url) == "table" then if base.type(base_url) == "table" then
base_parsed = base_url
base_url = build(base_parsed) base_url = build(base_parsed)
else else
base_parsed = parse(base_url) base_parsed = parse(base_url)

View File

@ -6,7 +6,7 @@
* The penalty of calling select to avoid busy-wait is only paid when * The penalty of calling select to avoid busy-wait is only paid when
* the I/O call fail in the first place. * the I/O call fail in the first place.
* *
* RCS ID: $Id$ * RCS ID: $Id: usocket.c,v 1.38 2007/10/13 23:55:20 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
@ -368,3 +368,24 @@ const char *socket_ioerror(p_socket ps, int err) {
(void) ps; (void) ps;
return socket_strerror(err); return socket_strerror(err);
} }
const char *socket_gaistrerror(int err) {
if (err == 0) return NULL;
switch (err) {
case EAI_AGAIN: return "temporary failure in name resolution";
case EAI_BADFLAGS: return "invalid value for ai_flags";
case EAI_BADHINTS: return "invalid value for hints";
case EAI_FAIL: return "non-recoverable failure in name resolution";
case EAI_FAMILY: return "ai_family not supported";
case EAI_MEMORY: return "memory allocation failure";
case EAI_NONAME:
return "hostname or servname not provided, or not known";
case EAI_OVERFLOW: return "argument buffer overflow";
case EAI_PROTOCOL: return "resolved protocol is unknown";
case EAI_SERVICE: return "servname not supported for socktype";
case EAI_SOCKTYPE: return "ai_socktype not supported";
case EAI_SYSTEM: return strerror(errno);
default: return "unknown error";
}
}

View File

@ -5,7 +5,7 @@
* The penalty of calling select to avoid busy-wait is only paid when * The penalty of calling select to avoid busy-wait is only paid when
* the I/O call fail in the first place. * the I/O call fail in the first place.
* *
* RCS ID: $Id$ * RCS ID: $Id: wsocket.c,v 1.36 2007/06/11 23:44:54 diego Exp $
\*=========================================================================*/ \*=========================================================================*/
#include <string.h> #include <string.h>