mirror of
				https://github.com/lunarmodules/luasocket.git
				synced 2025-10-31 10:25:55 +01:00 
			
		
		
		
	Fixes suggested by @Florob in #147.
This commit is contained in:
		| @@ -65,6 +65,12 @@ href=#bind><tt>connect</tt></a>, depending on the address | |||||||
| family obtained from the resolver. | family obtained from the resolver. | ||||||
| </p> | </p> | ||||||
|  |  | ||||||
|  | <p class=note> | ||||||
|  | Note: Before the choice between IPv4 and IPv6 happens, | ||||||
|  | the internal socket object is invalid and therefore <a | ||||||
|  | href=#setoption><tt>setoption</tt></a> will fail. | ||||||
|  | </p> | ||||||
|  |  | ||||||
| <!-- socket.tcp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | <!-- socket.tcp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||||||
|  |  | ||||||
| <p class=name id="socket.tcp4"> | <p class=name id="socket.tcp4"> | ||||||
|   | |||||||
| @@ -76,6 +76,12 @@ href=#setsockname><tt>sockname</tt></a>, depending on the address | |||||||
| family obtained from the resolver. | family obtained from the resolver. | ||||||
| </p> | </p> | ||||||
|  |  | ||||||
|  | <p class=note> | ||||||
|  | Note: Before the choice between IPv4 and IPv6 happens, | ||||||
|  | the internal socket object is invalid and therefore <a | ||||||
|  | href=#setoption><tt>setoption</tt></a> will fail. | ||||||
|  | </p> | ||||||
|  |  | ||||||
| <!-- socket.udp4 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | <!-- socket.udp4 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||||||
|  |  | ||||||
| <p class="name" id="socket.udp"> | <p class="name" id="socket.udp"> | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								src/inet.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/inet.c
									
									
									
									
									
								
							| @@ -352,8 +352,13 @@ static void inet_pushresolved(lua_State *L, struct hostent *hp) | |||||||
| /*-------------------------------------------------------------------------*\ | /*-------------------------------------------------------------------------*\ | ||||||
| * Tries to create a new inet socket | * Tries to create a new inet socket | ||||||
| \*-------------------------------------------------------------------------*/ | \*-------------------------------------------------------------------------*/ | ||||||
| const char *inet_trycreate(p_socket ps, int family, int type) { | const char *inet_trycreate(p_socket ps, int family, int type, int protocol) { | ||||||
|     return socket_strerror(socket_create(ps, family, type, 0)); |     const char *err = socket_strerror(socket_create(ps, family, type, protocol)); | ||||||
|  |     if (err == NULL && family == AF_INET6) { | ||||||
|  |         int yes = 1; | ||||||
|  |         setsockopt(*ps, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&yes, sizeof(yes)); | ||||||
|  |     } | ||||||
|  |     return err; | ||||||
| } | } | ||||||
|  |  | ||||||
| /*-------------------------------------------------------------------------*\ | /*-------------------------------------------------------------------------*\ | ||||||
| @@ -408,8 +413,8 @@ const char *inet_tryconnect(p_socket ps, int *family, const char *address, | |||||||
|          * not enter this branch. */ |          * not enter this branch. */ | ||||||
|         if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) { |         if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) { | ||||||
|             socket_destroy(ps); |             socket_destroy(ps); | ||||||
|             err = socket_strerror(socket_create(ps, iterator->ai_family, |             err = inet_trycreate(ps, iterator->ai_family, | ||||||
|                 iterator->ai_socktype, iterator->ai_protocol)); |                 iterator->ai_socktype, iterator->ai_protocol); | ||||||
|             if (err) continue; |             if (err) continue; | ||||||
|             current_family = iterator->ai_family; |             current_family = iterator->ai_family; | ||||||
|             /* set non-blocking before connect */ |             /* set non-blocking before connect */ | ||||||
| @@ -466,8 +471,8 @@ const char *inet_trybind(p_socket ps, int *family, const char *address, | |||||||
|     for (iterator = resolved; iterator; iterator = iterator->ai_next) { |     for (iterator = resolved; iterator; iterator = iterator->ai_next) { | ||||||
|         if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) { |         if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) { | ||||||
|             socket_destroy(ps); |             socket_destroy(ps); | ||||||
|             err = socket_strerror(socket_create(ps, iterator->ai_family, |             err = inet_trycreate(ps, iterator->ai_family, | ||||||
|                         iterator->ai_socktype, iterator->ai_protocol)); |                         iterator->ai_socktype, iterator->ai_protocol); | ||||||
|             if (err) continue; |             if (err) continue; | ||||||
|             current_family = iterator->ai_family; |             current_family = iterator->ai_family; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ | |||||||
|  |  | ||||||
| int inet_open(lua_State *L); | int inet_open(lua_State *L); | ||||||
|  |  | ||||||
| const char *inet_trycreate(p_socket ps, int family, int type); | const char *inet_trycreate(p_socket ps, int family, int type, int protocol); | ||||||
| const char *inet_tryconnect(p_socket ps, int *family, const char *address, | const char *inet_tryconnect(p_socket ps, int *family, const char *address, | ||||||
|         const char *serv, p_timeout tm, struct addrinfo *connecthints); |         const char *serv, p_timeout tm, struct addrinfo *connecthints); | ||||||
| const char *inet_trybind(p_socket ps, int *family, const char *address, | const char *inet_trybind(p_socket ps, int *family, const char *address, | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								src/tcp.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								src/tcp.c
									
									
									
									
									
								
							| @@ -355,39 +355,29 @@ static int meth_settimeout(lua_State *L) | |||||||
| * Creates a master tcp object | * Creates a master tcp object | ||||||
| \*-------------------------------------------------------------------------*/ | \*-------------------------------------------------------------------------*/ | ||||||
| static int tcp_create(lua_State *L, int family) { | static int tcp_create(lua_State *L, int family) { | ||||||
|     t_socket sock; |     p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | ||||||
|     /* if family is AF_UNSPEC, we create an AF_INET socket |     memset(tcp, 0, sizeof(t_tcp)); | ||||||
|      * but store AF_UNSPEC into tcp-family. This will allow it |     /* set its type as master object */ | ||||||
|      * later be replaced with an AF_INET6 socket if |     auxiliar_setclass(L, "tcp{master}", -1); | ||||||
|      * trybind or tryconnect prefer it instead. */ |     /* if family is AF_UNSPEC, we leave the socket invalid and | ||||||
|     const char *err = inet_trycreate(&sock, family == AF_UNSPEC? |      * store AF_UNSPEC into family. This will allow it to later be | ||||||
|         AF_INET: family, SOCK_STREAM); |      * replaced with an AF_INET6 or AF_INET socket upon first use. */ | ||||||
|     /* try to allocate a system socket */ |     tcp->sock = SOCKET_INVALID; | ||||||
|     if (!err) { |     tcp->family = family; | ||||||
|         /* allocate tcp object */ |     io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, | ||||||
|         p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); |             (p_error) socket_ioerror, &tcp->sock); | ||||||
|         memset(tcp, 0, sizeof(t_tcp)); |     timeout_init(&tcp->tm, -1, -1); | ||||||
|         /* set its type as master object */ |     buffer_init(&tcp->buf, &tcp->io, &tcp->tm); | ||||||
|         auxiliar_setclass(L, "tcp{master}", -1); |     if (family != AF_UNSPEC) { | ||||||
|         /* initialize remaining structure fields */ |         const char *err = inet_trycreate(&tcp->sock, family, SOCK_STREAM, 0); | ||||||
|         socket_setnonblocking(&sock); |         if (err != NULL) { | ||||||
|         if (family == AF_INET6) { |             lua_pushnil(L); | ||||||
|             int yes = 1; |             lua_pushstring(L, err); | ||||||
|             setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, |             return 2; | ||||||
|                 (void *)&yes, sizeof(yes)); |  | ||||||
|         } |         } | ||||||
|         tcp->sock = sock; |         socket_setnonblocking(&tcp->sock); | ||||||
|         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->family = family; |  | ||||||
|         return 1; |  | ||||||
|     } else { |  | ||||||
|         lua_pushnil(L); |  | ||||||
|         lua_pushstring(L, err); |  | ||||||
|         return 2; |  | ||||||
|     } |     } | ||||||
|  |     return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int global_create(lua_State *L) { | static int global_create(lua_State *L) { | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								src/udp.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								src/udp.c
									
									
									
									
									
								
							| @@ -365,7 +365,6 @@ static int meth_setpeername(lua_State *L) { | |||||||
|         inet_trydisconnect(&udp->sock, udp->family, tm); |         inet_trydisconnect(&udp->sock, udp->family, tm); | ||||||
|         auxiliar_setclass(L, "udp{unconnected}", 1); |         auxiliar_setclass(L, "udp{unconnected}", 1); | ||||||
|     } |     } | ||||||
|     /* change class to connected or unconnected depending on address */ |  | ||||||
|     lua_pushnumber(L, 1); |     lua_pushnumber(L, 1); | ||||||
|     return 1; |     return 1; | ||||||
| } | } | ||||||
| @@ -410,34 +409,25 @@ static int meth_setsockname(lua_State *L) { | |||||||
| * Creates a master udp object | * Creates a master udp object | ||||||
| \*-------------------------------------------------------------------------*/ | \*-------------------------------------------------------------------------*/ | ||||||
| static int udp_create(lua_State *L, int family) { | static int udp_create(lua_State *L, int family) { | ||||||
|     t_socket sock; |     /* allocate udp object */ | ||||||
|     /* if family is AF_UNSPEC, we create an AF_INET socket |     p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); | ||||||
|      * but store AF_UNSPEC into tcp-family. This will allow it |     auxiliar_setclass(L, "udp{unconnected}", -1); | ||||||
|      * later be replaced with an AF_INET6 socket if |     /* if family is AF_UNSPEC, we leave the socket invalid and | ||||||
|      * trybind or tryconnect prefer it instead. */ |      * store AF_UNSPEC into family. This will allow it to later be | ||||||
|     const char *err = inet_trycreate(&sock, family == AF_UNSPEC? |      * replaced with an AF_INET6 or AF_INET socket upon first use. */ | ||||||
|         AF_INET: family, SOCK_DGRAM); |     udp->sock = SOCKET_INVALID; | ||||||
|     /* try to allocate a system socket */ |     timeout_init(&udp->tm, -1, -1); | ||||||
|     if (!err) { |     udp->family = family; | ||||||
|         /* allocate udp object */ |     if (family != AF_UNSPEC) { | ||||||
|         p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); |         const char *err = inet_trycreate(&udp->sock, family, SOCK_DGRAM, 0); | ||||||
|         auxiliar_setclass(L, "udp{unconnected}", -1); |         if (err != NULL) { | ||||||
|         /* initialize remaining structure fields */ |             lua_pushnil(L); | ||||||
|         socket_setnonblocking(&sock); |             lua_pushstring(L, err); | ||||||
|         if (family == AF_INET6) { |             return 2; | ||||||
|             int yes = 1; |  | ||||||
|             setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, |  | ||||||
|                 (void *)&yes, sizeof(yes)); |  | ||||||
|         } |         } | ||||||
|         udp->sock = sock; |         socket_setnonblocking(&udp->sock); | ||||||
|         timeout_init(&udp->tm, -1, -1); |  | ||||||
|         udp->family = family; |  | ||||||
|         return 1; |  | ||||||
|     } else { |  | ||||||
|         lua_pushnil(L); |  | ||||||
|         lua_pushstring(L, err); |  | ||||||
|         return 2; |  | ||||||
|     } |     } | ||||||
|  |     return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int global_create(lua_State *L) { | static int global_create(lua_State *L) { | ||||||
|   | |||||||
| @@ -304,15 +304,20 @@ function isclosed(c) | |||||||
| end | end | ||||||
|  |  | ||||||
| function active_close() | function active_close() | ||||||
|     reconnect() |     local tcp = socket.tcp4() | ||||||
|     if isclosed(data) then fail("should not be closed") end |     if isclosed(tcp) then fail("should not be closed") end | ||||||
|     data:close() |     tcp:close() | ||||||
|     if not isclosed(data) then fail("should be closed") end |     if not isclosed(tcp) then fail("should be closed") end | ||||||
|     data = nil |     tcp = socket.tcp() | ||||||
|     local udp = socket.udp() |     if not isclosed(tcp) then fail("should be closed") end | ||||||
|  |     tcp = nil | ||||||
|  |     local udp = socket.udp4() | ||||||
|     if isclosed(udp) then fail("should not be closed") end |     if isclosed(udp) then fail("should not be closed") end | ||||||
|     udp:close() |     udp:close() | ||||||
|     if not isclosed(udp) then fail("should be closed") end |     if not isclosed(udp) then fail("should be closed") end | ||||||
|  |     udp = socket.udp() | ||||||
|  |     if not isclosed(udp) then fail("should be closed") end | ||||||
|  |     udp = nil | ||||||
|     pass("ok") |     pass("ok") | ||||||
| end | end | ||||||
|  |  | ||||||
| @@ -368,7 +373,7 @@ function test_selectbugs() | |||||||
|     pass("invalid input: ok") |     pass("invalid input: ok") | ||||||
|     local toomany = {} |     local toomany = {} | ||||||
|     for i = 1, socket._SETSIZE+1 do |     for i = 1, socket._SETSIZE+1 do | ||||||
|         toomany[#toomany+1] = socket.udp() |         toomany[#toomany+1] = socket.udp4() | ||||||
|     end |     end | ||||||
|     if #toomany > socket._SETSIZE then |     if #toomany > socket._SETSIZE then | ||||||
|         local e = pcall(socket.select, toomany, nil, 0.1) |         local e = pcall(socket.select, toomany, nil, 0.1) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user