ImportC openssl/ssl.h iossues due to inttypes.h

Witold Baryluk witold.baryluk+d at gmail.com
Sun May 24 01:52:25 UTC 2026


Complete real-life example usage that might be useful

```d
#!/usr/bin/env -S gdc -run -lssl -lcrypto

// gcc -E -P '-D__restrict= ' '-D__extension__= ' '-D__asm__(x)= 
' -std=c11 /usr/include/openssl/ssl.h > ssl.i
// gcc -E -P '-D__restrict= ' '-D__extension__= ' '-D__asm__(x)= 
' -std=c11 /usr/include/openssl/err.h > err.i
//
// gdc example.d -lssl -lcrypto
//
// You can ignore most warnings about
//  - conflicting types for built-in function ‘vsscanf’ and 
similar
// they are harmless to big extent.


import core.sys.posix.sys.socket;
import core.sys.posix.netinet.in_;
import core.sys.posix.arpa.inet;
import core.sys.posix.netdb : hostent, gethostbyname;
import core.sys.posix.unistd;
import core.stdc.string : memcpy;
import core.stdc.stdio : stderr;
import core.stdc.stdlib;

import std.string : toStringz;

// Explicitly define missing constants
enum SSL_VERIFY_PEER = 0x01;
enum SSL_VERIFY_NONE = 0x00;
enum SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 0x02;


enum SSL_CTRL_SET_TLSEXT_HOSTNAME = 55;  // Defined in OpenSSL
enum TLSEXT_NAMETYPE_host_name = 0x0;  // Defined in OpenSSL


void main() {
   import ssl;
   import err;

   SSL_METHOD* method = TLS_client_method();
   SSL_CTX* ctx = SSL_CTX_new(method);
   if (ctx is null) {
     ERR_print_errors_fp(cast(_IO_FILE*)stderr);
     return;
   }
   scope(exit) SSL_CTX_free(ctx);

   SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, null);
   SSL_CTX_set_default_verify_paths(ctx);

   int sock = socket(AF_INET, SOCK_STREAM, 0);
   if (sock < 0) {
     perror("socket");
     return;
   }
   scope(exit) close(sock);

   string hostname = "example.com";

   hostent* host = gethostbyname(toStringz(hostname));
   if (host is null) {
     perror("gethostbyname");
     return;
   }

   sockaddr_in addr;
   addr.sin_family = AF_INET;
   addr.sin_port = htons(443);

   // Copy first IP address
   memcpy(&addr.sin_addr, host.h_addr_list[0], host.h_length);

   if (connect(sock, cast(sockaddr*)&addr, sockaddr_in.sizeof) != 
0) {
     return;
   }

   SSL* s = SSL_new(ctx);
   scope(exit) SSL_free(s);

   SSL_set_fd(s, sock);

   // SSL_CTX_set_tlsext_host_name is a macro, so lets expand 
things.

   if (SSL_ctrl(s, SSL_CTRL_SET_TLSEXT_HOSTNAME, 
TLSEXT_NAMETYPE_host_name, cast(void*)toStringz(hostname)) != 1) {
     ERR_print_errors_fp(cast(_IO_FILE*)stderr);
     return;
   }

   if (SSL_connect(s) <= 0) {
     ERR_print_errors_fp(cast(_IO_FILE*)stderr);
     return;
   }
   scope(exit) SSL_shutdown(s);

   string request =
     "GET / HTTP/1.1\r\n" ~
     "Host: example.com\r\n" ~
     "Connection: close\r\n\r\n";

   SSL_write(s, request.ptr, cast(int)request.length);

   ubyte[4096] buffer;
   int bytes;

   while ((bytes = SSL_read(s, buffer.ptr, buffer.length)) > 0) {
     fwrite(buffer.ptr, 1, bytes, stdout);
   }

   return;
}
```


More information about the D.gnu mailing list