diff --git a/kc3_http/configure b/kc3_http/configure
index 60de918..a4c02b1 100755
--- a/kc3_http/configure
+++ b/kc3_http/configure
@@ -21,10 +21,10 @@ CONFIG_H_PREFIX=KC3_HTTP_
. ../config.subr
-LIB=libekc3.la
-LIB_ASAN=libekc3_asan.la
-LIB_COV=libekc3_cov.la
-LIB_DEBUG=libekc3_debug.la
+LIB=libkc3_http.la
+LIB_ASAN=libkc3_http_asan.la
+LIB_COV=libkc3_http_cov.la
+LIB_DEBUG=libkc3_http_debug.la
echo "LIB = $LIB" >> ${CONFIG_MK}
echo "LIB_ASAN = $LIB_ASAN" >> ${CONFIG_MK}
diff --git a/kc3_http/socket.c b/kc3_http/socket.c
index 9cc480d..19e6ace 100644
--- a/kc3_http/socket.c
+++ b/kc3_http/socket.c
@@ -11,45 +11,90 @@
* THIS SOFTWARE.
*/
#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
-#include <netdb.h>
+#include <unistd.h>
#include <libkc3/kc3.h>
#include "socket.h"
-int * socket_init_listen(int *s, const s_str *host, u16 port)
+void socket_clean (p_socket s)
+{
+ assert(s);
+ close(*s);
+ *s = 0;
+}
+
+p_socket socket_init_listen (p_socket s, const s_str *host, u16 port)
{
- struct sockaddr *addr;
- socklen_t addr_len;
- sw e;
- struct hostent *hostent;
- assert(s);
- assert(host);
- hostent = gethostbyname2(host->ptr.pchar, AF_INET);
- if (! hostent) {
- e = errno;
- err_write_1("socket_init_listen: gethostbyname2: ");
- err_puts(strerror(e));
- assert(!"socket_init_listen: gethostbyname2");
- return NULL;
- }
- addr = (struct sockaddr *) hostent->h_addr_list[0];
- addr_len = hostent->h_length;
- socket = socket(addr->sa_family, SOCK_STREAM, 0);
- if (socket < 0) {
- e = errno;
- err_write_1("socket_init_listen: socket: ");
- err_puts(strerror(e));
- assert(! "socket_init_listen: socket");
- return NULL;
- }
- addr->port = htons(port);
- if (bind(socket, addr, addr_len) < 0) {
- e = errno;
- err_write_1("socket_init_listen: bind: ");
- err_puts(strerror(e));
- assert(! "socket_init_listen: bind");
- return NULL;
- }
- return s;
-}
\ No newline at end of file
+ struct sockaddr *addr;
+ struct sockaddr_in *addr_inet;
+ struct sockaddr_in6 *addr_inet6;
+ socklen_t addr_len;
+ sw e;
+ struct hostent *hostent;
+ t_socket tmp;
+ assert(s);
+ assert(host);
+ hostent = gethostbyname2(host->ptr.pchar, AF_INET);
+ if (! hostent)
+ hostent = gethostbyname2(host->ptr.pchar, AF_INET6);
+ if (! hostent) {
+ e = errno;
+ err_write_1("socket_init_listen: gethostbyname2: ");
+ err_puts(strerror(e));
+ assert(!"socket_init_listen: gethostbyname2");
+ return NULL;
+ }
+ addr_len = hostent->h_length;
+ addr = alloc(addr_len);
+ if (! addr)
+ return NULL;
+ memcpy(addr, hostent->h_addr_list[0], addr_len);
+ switch (addr->sa_family) {
+ case AF_INET:
+ addr_inet = (struct sockaddr_in *) addr;
+ addr_inet->sin_port = htons(port);
+ break;
+ case AF_INET6:
+ addr_inet6 = (struct sockaddr_in6 *) addr;
+ addr_inet6->sin6_port = htons(port);
+ break;
+ default:
+ err_puts("socket_init_listen: unknown address family");
+ assert(! "socket_init_listen: unknown address family");
+ free(addr);
+ return NULL;
+ }
+ tmp = socket(addr->sa_family, SOCK_STREAM, 0);
+ if (tmp < 0) {
+ e = errno;
+ err_write_1("socket_init_listen: socket: ");
+ err_puts(strerror(e));
+ assert(! "socket_init_listen: socket");
+ free(addr);
+ return NULL;
+ }
+ if (bind(tmp, addr, addr_len) < 0) {
+ e = errno;
+ err_write_1("socket_init_listen: bind: ");
+ err_puts(strerror(e));
+ assert(! "socket_init_listen: bind");
+ socket_clean(&tmp);
+ free(addr);
+ return NULL;
+ }
+ free(addr);
+ if (listen(tmp, SOMAXCONN) < 0) {
+ e = errno;
+ err_write_1("socket_init_listen: listen: ");
+ err_puts(strerror(e));
+ assert(! "socket_init_listen: listen");
+ socket_clean(&tmp);
+ free(addr);
+ return NULL;
+ }
+ *s = tmp;
+ return s;
+}
diff --git a/kc3_http/socket.h b/kc3_http/socket.h
index fd5b606..a0b4fc9 100644
--- a/kc3_http/socket.h
+++ b/kc3_http/socket.h
@@ -15,6 +15,10 @@
#include "types.h"
-int * socket_init_listen(int *s, const s_str *host, u16 port);
+/* Stack-allocation compatible functions, call socket_clean after
+ use. */
+void socket_clean (p_socket s);
+p_socket socket_init_listen (p_socket s, const s_str *host, u16 port);
+p_socket socket_init_accept (p_socket s, p_socket listening);
#endif /* SOCKET_H */
diff --git a/kc3_http/types.h b/kc3_http/types.h
index 6b1ec85..ff12d73 100644
--- a/kc3_http/types.h
+++ b/kc3_http/types.h
@@ -15,6 +15,10 @@
#include <libkc3/types.h>
-typedef s_list *p_http;
+/* 1 */
+typedef int t_socket;
+
+/* 2 */
+typedef t_socket *p_socket;
#endif /* HTTP_TYPES_H */
diff --git a/libkc3/kc3.h b/libkc3/kc3.h
index 07cc81e..7eb6f3b 100644
--- a/libkc3/kc3.h
+++ b/libkc3/kc3.h
@@ -13,6 +13,7 @@
#ifndef LIBKC3_KC3_H
#define LIBKC3_KC3_H
+#include "alloc.h"
#include "arg.h"
#include "array.h"
#include "assert.h"