diff --git a/ip.c b/ip.c index 4a9da30..dd1d51e 100644 --- a/ip.c +++ b/ip.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -99,11 +100,32 @@ static ipaddr mill_ipv4_literal(const char *addr, int port) { static ipaddr mill_ipv6_literal(const char *addr, int port) { ipaddr raddr; struct sockaddr_in6 *ipv6 = (struct sockaddr_in6*)&raddr; + struct sockaddr_in6 *sockv6; + char str[IPADDR_MAXSTRLEN]; int rc = inet_pton(AF_INET6, addr, &ipv6->sin6_addr); mill_assert(rc >= 0); if(rc == 1) { ipv6->sin6_family = AF_INET6; ipv6->sin6_port = htons((uint16_t)port); + /* Grab IPv6 Scope ID from the IPv6 address. */ + struct ifaddrs *ifaces = NULL; + int rc = getifaddrs (&ifaces); + mill_assert (rc == 0); + mill_assert (ifaces); + struct ifaddrs *ifv6 = NULL; + struct ifaddrs *it; + for(it = ifaces; it != NULL; it = it->ifa_next) { + if(!it->ifa_addr) + continue; + if(it->ifa_addr->sa_family == AF_INET6){ + sockv6 = (struct sockaddr_in6 *)it->ifa_addr; + inet_ntop(AF_INET6, &(sockv6->sin6_addr), str, IPADDR_MAXSTRLEN); + ipv6->sin6_scope_id = 2; + if(strcmp(str, addr) == 0){ + ipv6->sin6_scope_id = if_nametoindex(it->ifa_name); + } + } + } errno = 0; return raddr; } @@ -237,7 +259,8 @@ ipaddr mill_iplocal_(const char *name, int port, int mode) { struct sockaddr_in6 *inaddr = (struct sockaddr_in6*)&addr; memcpy(inaddr, ipv6->ifa_addr, sizeof (struct sockaddr_in6)); inaddr->sin6_port = htons(port); - freeifaddrs(ifaces); + inaddr->sin6_scope_id = if_nametoindex(ipv6->ifa_name); + freeifaddrs(ifaces); errno = 0; return addr; } @@ -355,7 +378,7 @@ ipaddr mill_ipremote_(const char *name, int port, int mode, int64_t deadline) { struct sockaddr_in6 *inaddr = (struct sockaddr_in6*)&addr; memcpy(inaddr, ipv6->ai_addr, sizeof (struct sockaddr_in6)); inaddr->sin6_port = htons(port); - dns_ai_close(ai); + dns_ai_close(ai); free(ipv6); errno = 0; return addr; diff --git a/libmill.h b/libmill.h index 2e8693b..810fe33 100644 --- a/libmill.h +++ b/libmill.h @@ -640,16 +640,27 @@ typedef struct mill_unixsock *unixsock; /******************************************************************************/ struct mill_sslsock; +typedef struct sslserver { + //const char* addr; + //uint32_t port; + ipaddr addr; + void *method; + const char *cert_file; + const char *key_file; +} SSLSERVER_st, *SSLSERVER_p_st; +typedef struct sslclient { + struct mill_ipaddr addr; + void *method; + const char *cert_file; +} SSLCLIENT_st, *SSLCLIENT_p_st; MILL_EXPORT struct mill_sslsock *mill_ssllisten_( - struct mill_ipaddr addr, - const char *cert_file, - const char *key_file, + SSLSERVER_p_st server, int backlog); MILL_EXPORT int mill_sslport_( struct mill_sslsock *s); MILL_EXPORT struct mill_sslsock *mill_sslconnect_( - struct mill_ipaddr addr, + SSLCLIENT_p_st client, int64_t deadline); MILL_EXPORT struct mill_sslsock *mill_sslaccept_( struct mill_sslsock *s, diff --git a/ssl.c b/ssl.c index b7f5613..eb8fb5c 100644 --- a/ssl.c +++ b/ssl.c @@ -67,31 +67,33 @@ static void ssl_init(void) { initialised = 1; OpenSSL_add_all_algorithms(); SSL_library_init(); - - /* TODO: Move to sslconnect() */ - ssl_cli_ctx = SSL_CTX_new(SSLv23_client_method()); - mill_assert(ssl_cli_ctx); } -struct mill_sslsock *mill_ssllisten_(struct mill_ipaddr addr, - const char *cert_file, const char *key_file, int backlog) { +struct mill_sslsock *mill_ssllisten_(SSLSERVER_p_st server, int backlog) { ssl_init(); /* Load certificates. */ - SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); + SSL_CTX *ctx; + if(server->method != NULL){ + ctx = SSL_CTX_new((SSL_METHOD*)server->method); + } else { + ctx = SSL_CTX_new(TLSv1_2_server_method()); + } if(!ctx) return NULL; - if(cert_file && SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) + if(server->cert_file && SSL_CTX_use_certificate_chain_file(ctx, server->cert_file) <= 0) return NULL; - if(key_file && SSL_CTX_use_PrivateKey_file(ctx, - key_file, SSL_FILETYPE_PEM) <= 0) + if(server->key_file && SSL_CTX_use_PrivateKey_file(ctx, + server->key_file, SSL_FILETYPE_PEM) <= 0) return NULL; /* Check for inconsistent private key. */ if(SSL_CTX_check_private_key(ctx) <= 0) return NULL; /* Open the listening socket. */ - tcpsock s = tcplisten(addr, backlog); + //ipaddr laddr = iplocal((const char*)server->addr, server->port, 0); + tcpsock s = tcplisten(server->addr, backlog); if(!s) { /* TODO: close the context */ + printf("error was exacltly here."); return NULL; } /* Create the object. */ @@ -286,10 +288,13 @@ void mill_sslflush_(struct mill_sslsock *s, int64_t deadline) { errno = 0; } -struct mill_sslsock *mill_sslconnect_(struct mill_ipaddr addr, +struct mill_sslsock *mill_sslconnect_(SSLCLIENT_p_st client, int64_t deadline) { ssl_init(); - tcpsock sock = tcpconnect(addr, deadline); + ssl_cli_ctx = SSL_CTX_new((SSL_METHOD*)client->method); + mill_assert(ssl_cli_ctx); + + tcpsock sock = tcpconnect(client->addr, deadline); if(!sock) return NULL; struct mill_sslsock *c = ssl_conn_new(sock, ssl_cli_ctx, 1); diff --git a/tests/ssl.c b/tests/ssl.c index 932be9e..66e16aa 100644 --- a/tests/ssl.c +++ b/tests/ssl.c @@ -66,9 +66,12 @@ coroutine void client2(int port) { int main() { char buf[16]; - - sslsock ls = ssllisten(iplocal(NULL, 5555, 0), - "./tests/cert.pem", "./tests/key.pem", 10); + SSLSERVER_p_st ss = malloc(sizeof(SSLSERVER_st)); + ss->method = NULL; + ss->addr = iplocal(NULL, 5555, 0); + ss->cert_file = "./tests/cert.pem"; + ss->key_file = "./tests/key.pem"; + sslsock ls = ssllisten(ss, 10); assert(ls); go(client(5555)); @@ -105,8 +108,12 @@ int main() { sslclose(ls); /* Test whether libmill performs correctly when faced with TCP pushback. */ - ls = ssllisten(iplocal(NULL, 5555, 0), - "./tests/cert.pem", "./tests/key.pem", 10); + ss->method = NULL; + ss->addr = iplocal(NULL, 5555, 0); + ss->cert_file ="./tests/cert.pem"; + ss->key_file ="./tests/key.pem"; + ls = ssllisten(ss, 10); + go(client2(5555)); as = sslaccept(ls, -1); assert(as); @@ -130,7 +137,7 @@ int main() { } sslclose(as); sslclose(ls); - + free(ss); return 0; } diff --git a/tutorial/step8.c b/tutorial/step8.c index 13594ea..2650389 100644 --- a/tutorial/step8.c +++ b/tutorial/step8.c @@ -28,7 +28,7 @@ #include #include #include - +#include #include "../libmill.h" #define CONN_ESTABLISHED 1 @@ -94,7 +94,6 @@ coroutine void dialogue(sslsock as, chan ch) { } int main(int argc, char *argv[]) { - int port = 5555; int nproc = 1; if(argc > 1) @@ -103,7 +102,14 @@ int main(int argc, char *argv[]) { nproc = atoi(argv[2]); ipaddr addr = iplocal(NULL, port, 0); - sslsock ls = ssllisten(addr, "./cert.pem", "./key.pem", 10); + + SSLSERVER_p_st ss = malloc(sizeof(SSLSERVER_st)); + ss->method = (SSL_METHOD*) TLSv1_2_server_method(); + ss->addr = addr; + //ss->port = port; + ss->cert_file = "./cert.pem"; + ss->key_file = "./key.pem"; + sslsock ls = ssllisten(ss, 10); if(!ls) { perror("Can't open listening socket"); return 1;