decompiled_code:
void __fastcall __noreturn start_shoveler(int fd)
{
__int64 v1; // r12
int v2; // ebp
_BYTE v3[4240]; // [rsp+0h] [rbp-11D8h] BYREF
char v4[8]; // [rsp+1090h] [rbp-148h] BYREF
__int64 v5; // [rsp+1098h] [rbp-140h]
int v6; // [rsp+10B0h] [rbp-128h]
int v7[24]; // [rsp+10D0h] [rbp-108h] BYREF
struct timeval timeout; // [rsp+1130h] [rbp-A8h] BYREF
fd_set readfds; // [rsp+1140h] [rbp-98h] BYREF

init_cnx(v4);
v6 = fd;
memset(&readfds, 0, sizeof(readfds));
v1 = 1LL << (fd % 64);
readfds.fds_bits[fd / 64] |= v1;
timeout.tv_usec = 0LL;
timeout.tv_sec = cfg[16];
while ( 1 )
{
if ( select(fd + 1, &readfds, 0LL, 0LL, &timeout) == -1 )
perror("select");
if ( (readfds.fds_bits[fd / 64] & v1) == 0 )
break;
if ( (unsigned int)probe_client_protocol(v4) != 2 )
goto LABEL_7;
}
v5 = timeout_protocol();
print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "timed out, connect to %s\n", *(const char **)v5);
LABEL_7:
if ( !*(_QWORD *)(v5 + 32) || !(unsigned int)check_access_rights((unsigned int)fd) )
{
v2 = connect_addr(v4, (unsigned int)fd, 1LL);
if ( v2 != -1 )
{
set_capabilities(0LL);
v7[0] = v2;
get_connection_desc(v3, v4);
log_connection(v3, v4);
set_proctitle_shovel(v3, v4);
flush_deferred(v7);
shovel((__int64)v4);
close(fd);
close(v2);
print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "connection closed down\n");
exit(0);
}
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "sslh-fork.c", 114LL);
perror("connect");
exit(1);
}
exit(0);
}

canonical_decompiled_code:
void __fastcall __noreturn func2(int fd)
{
__int64 v1; // r12
int v2; // ebp
_BYTE v3[4240]; // [rsp+0h] [rbp-11D8h] BYREF
char v4[8]; // [rsp+1090h] [rbp-148h] BYREF
__int64 v5; // [rsp+1098h] [rbp-140h]
int v6; // [rsp+10B0h] [rbp-128h]
int v7[24]; // [rsp+10D0h] [rbp-108h] BYREF
struct timeval timeout; // [rsp+1130h] [rbp-A8h] BYREF
fd_set readfds; // [rsp+1140h] [rbp-98h] BYREF

init_cnx(v4);
v6 = fd;
memset(&readfds, 0, sizeof(readfds));
v1 = 1LL << (fd % 64);
readfds.fds_bits[fd / 64] |= v1;
timeout.tv_usec = 0LL;
timeout.tv_sec = cfg[16];
while ( 1 )
{
if ( select(fd + 1, &readfds, 0LL, 0LL, &timeout) == -1 )
perror("select");
if ( (readfds.fds_bits[fd / 64] & v1) == 0 )
break;
if ( (unsigned int)probe_client_protocol(v4) != 2 )
goto LABEL_7;
}
v5 = timeout_protocol();
print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "timed out, connect to %s\n", *(const char **)v5);
LABEL_7:
if ( !*(_QWORD *)(v5 + 32) || !(unsigned int)check_access_rights((unsigned int)fd) )
{
v2 = connect_addr(v4, (unsigned int)fd, 1LL);
if ( v2 != -1 )
{
set_capabilities(0LL);
v7[0] = v2;
get_connection_desc(v3, v4);
log_connection(v3, v4);
set_proctitle_shovel(v3, v4);
flush_deferred(v7);
func1((__int64)v4);
close(fd);
close(v2);
print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "connection closed down\n");
exit(0);
}
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "sslh-fork.c", 114LL);
perror("connect");
exit(1);
}
exit(0);
}

original_code:
void start_shoveler(int in_socket)
{
   fd_set fds;
   struct timeval tv;
   int res = PROBE_AGAIN;
   int out_socket;
   struct connection cnx;
   struct connection_desc desc;
   init_cnx(&cnx);
   cnx.q[0].fd = in_socket;
   do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&fds)->fds_bits)[0]) : "memory"); } while (0);
   ((void) (((&fds)->fds_bits)[((in_socket) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((in_socket) % (8 * (int) sizeof (__fd_mask)))))));
   memset(&tv, 0, sizeof(tv));
   tv.tv_sec = cfg.timeout;
   while (res == PROBE_AGAIN) {
       res = select(in_socket + 1, &fds, ((void *)0), ((void *)0), &tv);
       if (res == -1)
           perror("select");
       if (((((&fds)->fds_bits)[((in_socket) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((in_socket) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
           res = probe_client_protocol(&cnx);
       } else {
           cnx.proto = timeout_protocol();
           print_message(msg_fd, "timed out, connect to %s\n", cnx.proto->name);
           break;
       }
   }
   if (cnx.proto->service &&
       check_access_rights(in_socket, cnx.proto->service)) {
       exit(0);
   }
   out_socket = connect_addr(&cnx, in_socket, BLOCKING);
   if (out_socket == -1) { print_message(msg_system_error, "%s:%d:", "sslh-fork.c", 114); perror("connect"); exit(1); };
   set_capabilities(0);
   cnx.q[1].fd = out_socket;
   get_connection_desc(&desc, &cnx);
   log_connection(&desc, &cnx);
   set_proctitle_shovel(&desc, &cnx);
   flush_deferred(&cnx.q[1]);
   shovel(&cnx);
   close(in_socket);
   close(out_socket);
   print_message(msg_fd, "connection closed down\n");
   exit(0);
}

canonical_original_code:
void start_shoveler(int in_socket)
{
   struct fd_set fds;
   struct timeval tv;
   int res = PROBE_AGAIN;
   int out_socket;
   struct connection cnx;
   struct connection_desc desc;
   init_cnx(&cnx);
   cnx.q[0].fd = in_socket;
   do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&fds)->fds_bits)[0]) : "memory"); } while (0);
   ((void) (((&fds)->fds_bits)[((in_socket) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((in_socket) % (8 * (int) sizeof (__fd_mask)))))));
   memset(&tv, 0, sizeof(tv));
   tv.tv_sec = cfg.timeout;
   while (res == PROBE_AGAIN) {
       res = select(in_socket + 1, &fds, ((void *)0), ((void *)0), &tv);
       if (res == -1)
           perror("select");
       if (((((&fds)->fds_bits)[((in_socket) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((in_socket) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
           res = probe_client_protocol(&cnx);
       } else {
           cnx.proto = timeout_protocol();
           print_message(msg_fd, "timed out, connect to %s\n", cnx.proto->name);
           break;
       }
   }
   if (cnx.proto->service &&
       check_access_rights(in_socket, cnx.proto->service)) {
       exit(0);
   }
   out_socket = connect_addr(&cnx, in_socket, BLOCKING);
   if (out_socket == -1) { print_message(msg_system_error, "%s:%d:", "sslh-fork.c", 114); perror("connect"); exit(1); };
   set_capabilities(0);
   cnx.q[1].fd = out_socket;
   get_connection_desc(&desc, &cnx);
   log_connection(&desc, &cnx);
   set_proctitle_shovel(&desc, &cnx);
   flush_deferred(&cnx.q[1]);
   shovel(&cnx);
   close(in_socket);
   close(out_socket);
   print_message(msg_fd, "connection closed down\n");
   exit(0);
}

variable_types: struct timeval { long tv_sec; long tv_usec; }

variable_types: struct connection { int type; struct sslhcfg_protocols_item { char *name; char *host; char *port; int service_is_present; char *service; int is_udp; int udp_timeout; int fork; int tfo_ok; int transparent; int resolve_on_forward; int log_level; int keepalive; unsigned long sni_hostnames_len; char **sni_hostnames; unsigned long alpn_protocols_len; char **alpn_protocols; unsigned long regex_patterns_len; char **regex_patterns; int minlength_is_present; int minlength; int (*probe)(char *, long, struct sslhcfg_protocols_item *); struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *saddr; void *data; struct dl_list { struct connection *head; struct connection *tail; } timeouts; } *proto; enum connection_state { ST_PROBING=1, ST_SHOVELING=2 } state; long probe_timeout; struct queue { int fd; void *begin_deferred_data; void *deferred_data; int deferred_data_size; } q[2]; struct sockaddr client_addr; unsigned int addrlen; int local_endpoint; long last_active; struct connection *timeout_prev; int target_sock; }

variable_types: struct connection_desc { char peer[-1]; }


repo: yrutschle/sslh

decompiled_code:
__pid_t __fastcall main_loop(int *a1, int a2)
{
__int64 i; // rbx
int *v3; // rbp
char *v4; // rax
__pid_t *v5; // r15
int v6; // eax
struct sigaction v8; // [rsp+0h] [rbp-D8h] BYREF

listener_pid_number = a2;
listener_pid = (__int64)malloc(4LL * a2);
if ( !listener_pid )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "sslh-fork.c", 209LL);
perror("malloc");
exit(1);
}
tcp_init();
if ( a2 > 0 )
{
for ( i = 0LL; i != a2; ++i )
{
v5 = (__pid_t *)(listener_pid + 4 * i);
*v5 = fork();
v6 = *(_DWORD *)(listener_pid + 4 * i);
if ( v6 == -1 )
{
v3 = _errno_location();
v4 = strerror(*v3);
print_message(
msg_system_error,
*((_QWORD *)&msg_system_error + 1),
"fork failed: err %d: %s\n",
(unsigned int)*v3,
v4);
}
else if ( !v6 )
{
if ( a1[2 * i + 1] == 2 )
print_message(msg_config_error, *((_QWORD *)&msg_config_error + 1), "UDP not (yet?) supported in sslh-fork\n");
else
tcp_listener(a1, a2, i);
}
}
}
memset(&v8.sa_mask, 0, 0x90uLL);
v8.sa_handler = (__sighandler_t)stop_listeners;
if ( sigaction(15, &v8, 0LL) == -1 )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "sslh-fork.c", 241LL);
perror("sigaction");
exit(1);
}
return wait(0LL);
}

canonical_decompiled_code:
__pid_t __fastcall func5(int *a1, int a2)
{
__int64 i; // rbx
int *v3; // rbp
char *v4; // rax
__pid_t *v5; // r15
int v6; // eax
struct sigaction v8; // [rsp+0h] [rbp-D8h] BYREF

listener_pid_number = a2;
listener_pid = (__int64)malloc(4LL * a2);
if ( !listener_pid )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "sslh-fork.c", 209LL);
perror("malloc");
exit(1);
}
tcp_init();
if ( a2 > 0 )
{
for ( i = 0LL; i != a2; ++i )
{
v5 = (__pid_t *)(listener_pid + 4 * i);
*v5 = fork();
v6 = *(_DWORD *)(listener_pid + 4 * i);
if ( v6 == -1 )
{
v3 = _errno_location();
v4 = strerror(*v3);
print_message(
msg_system_error,
*((_QWORD *)&msg_system_error + 1),
"fork failed: err %d: %s\n",
(unsigned int)*v3,
v4);
}
else if ( !v6 )
{
if ( a1[2 * i + 1] == 2 )
print_message(msg_config_error, *((_QWORD *)&msg_config_error + 1), "UDP not (yet?) supported in sslh-fork\n");
else
func4(a1, a2, i);
}
}
}
memset(&v8.sa_mask, 0, 0x90uLL);
v8.sa_handler = (__sighandler_t)stop_listeners;
if ( sigaction(15, &v8, 0LL) == -1 )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "sslh-fork.c", 241LL);
perror("sigaction");
exit(1);
}
return wait(0LL);
}

original_code:
void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
{
    int i, res;
    struct sigaction action;
    listener_pid_number = num_addr_listen;
    listener_pid = malloc(listener_pid_number * sizeof(listener_pid[0]));
    if (!listener_pid) { print_message(msg_system_error, "%s:%d:", "sslh-fork.c", 209); perror("malloc"); exit(1); };
    tcp_init();
    for (i = 0; i < num_addr_listen; i++) {
        listener_pid[i] = fork();
        switch(listener_pid[i]) {
        case -1: print_message(msg_system_error, "fork failed: err %d: %s\n", (*__errno_location ()), strerror((*__errno_location ())));
                 break;
        case 0:
            set_listen_procname(&listen_sockets[i]);
            if (listen_sockets[i].type == SOCK_DGRAM)
                print_message(msg_config_error, "UDP not (yet?) supported in sslh-fork\n");
            else
                tcp_listener(listen_sockets, num_addr_listen, i);
     break;
 default:
     break;
        }
    }
    memset(&action, 0, sizeof(action));
    action.__sigaction_handler.sa_handler = stop_listeners;
    res = sigaction(15, &action, ((void *)0));
    if (res == -1) { print_message(msg_system_error, "%s:%d:", "sslh-fork.c", 241); perror("sigaction"); exit(1); };
    wait(((void *)0));
}

canonical_original_code:
void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
{
    int i; int res;
    struct sigaction action;
    listener_pid_number = num_addr_listen;
    listener_pid = malloc(listener_pid_number * sizeof(listener_pid[0]));
    if (!listener_pid) { print_message(msg_system_error, "%s:%d:", "sslh-fork.c", 209); perror("malloc"); exit(1); };
    tcp_init();
    for (i = 0; i < num_addr_listen; i++) {
        listener_pid[i] = fork();
        switch(listener_pid[i]) {
        case -1: print_message(msg_system_error, "fork failed: err %d: %s\n", (*__errno_location ()), strerror((*__errno_location ())));
                 break;
        case 0:
            set_listen_procname(&listen_sockets[i]);
            if (listen_sockets[i].type == SOCK_DGRAM)
                print_message(msg_config_error, "UDP not (yet?) supported in sslh-fork\n");
            else
                tcp_listener(listen_sockets, num_addr_listen, i);
     break;
 default:
     break;
        }
    }
    memset(&action, 0, sizeof(action));
    action.__sigaction_handler.sa_handler = stop_listeners;
    res = sigaction(15, &action, ((void *)0));
    if (res == -1) { print_message(msg_system_error, "%s:%d:", "sslh-fork.c", 241); perror("sigaction"); exit(1); };
    wait(((void *)0));
}

variable_types: struct listen_endpoint { int socketfd; int type; } []

variable_types: i int

variable_types: res int

variable_types: struct sigaction { union { void (*sa_handler)(int); void (*sa_sigaction)(int, struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval { int sival_int; void *sival_ptr; } si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; } *, void *); } __sigaction_handler; struct __sigset_t { unsigned long __val[-1]; } sa_mask; int sa_flags; void (*sa_restorer)(); }

return_type: void

user_defined_types: struct sigaction { union { void (*sa_handler)(int); void (*sa_sigaction)(int, struct siginfo_t *, void *); } __sigaction_handler; struct __sigset_t sa_mask; int sa_flags; void (*sa_restorer)(); }

user_defined_types: struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; }


decompiled_code:
void __fastcall __noreturn tcp_echo(int *a1)
{
int v1; // ebx

while ( 1 )
{
v1 = accept(*a1, 0LL, 0LL);
if ( v1 == -1 )
break;
if ( !fork() )
{
close(*a1);
start_echo(v1);
exit(0);
}
close(v1);
waitpid(-1, 0LL, 1);
}
perror("tcp_echo:accept");
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func0(int *a1)
{
int v1; // ebx

while ( 1 )
{
v1 = accept(*a1, 0LL, 0LL);
if ( v1 == -1 )
break;
if ( !fork() )
{
close(*a1);
start_echo(v1);
exit(0);
}
close(v1);
waitpid(-1, 0LL, 1);
}
perror("tcp_echo:accept");
exit(1);
}

original_code:
void tcp_echo(struct listen_endpoint* listen_socket)
{
    while (1) {
        int in_socket = accept(listen_socket->socketfd, 0, 0);
        if (in_socket == -1) {
            perror("tcp_echo:accept");
            exit(1);
        }
        if (!fork())
        {
            close(listen_socket->socketfd);
            start_echo(in_socket);
            exit(0);
        }
        close(in_socket);
        waitpid(-1, ((void *)0), 1);
    }
}

canonical_original_code:
void tcp_echo(struct listen_endpoint *listen_socket)
{
    while (1) {
        int in_socket = accept(listen_socket->socketfd, 0, 0);
        if (in_socket == -1) {
            perror("tcp_echo:accept");
            exit(1);
        }
        if (!fork())
        {
            close(listen_socket->socketfd);
            start_echo(in_socket);
            exit(0);
        }
        close(in_socket);
        waitpid(-1, ((void *)0), 1);
    }
}

variable_types: struct listen_endpoint { int socketfd; int type; } *


decompiled_code:
int __fastcall print_udp_xchange(int a1, __int64 a2)
{
char *v2; // rbx
char *v3; // rax
struct sockaddr v5[8]; // [rsp+0h] [rbp-948h] BYREF
char s[1072]; // [rsp+80h] [rbp-8C8h] BYREF
char v7[1072]; // [rsp+4B0h] [rbp-498h] BYREF
char v8[16]; // [rsp+8E0h] [rbp-68h] BYREF
int v9; // [rsp+8F0h] [rbp-58h]
__int64 v10; // [rsp+8F8h] [rbp-50h]
char v11[16]; // [rsp+910h] [rbp-38h] BYREF
socklen_t len; // [rsp+920h] [rbp-28h] BYREF
struct sockaddr *v13; // [rsp+928h] [rbp-20h]

v13 = v5;
len = 128;
getsockname(a1, v5, &len);
v10 = a2;
v9 = 16;
v2 = sprintaddr(s, 0x423uLL, (__int64)v8);
v3 = sprintaddr(v7, 0x423uLL, (__int64)v11);
return fprintf(stderr, "UDP local %s remote %s\n", v3, v2);
}

canonical_decompiled_code:
int __fastcall func3(int a1, __int64 a2)
{
char *v2; // rbx
char *v3; // rax
struct sockaddr v5[8]; // [rsp+0h] [rbp-948h] BYREF
char s[1072]; // [rsp+80h] [rbp-8C8h] BYREF
char v7[1072]; // [rsp+4B0h] [rbp-498h] BYREF
char v8[16]; // [rsp+8E0h] [rbp-68h] BYREF
int v9; // [rsp+8F0h] [rbp-58h]
__int64 v10; // [rsp+8F8h] [rbp-50h]
char v11[16]; // [rsp+910h] [rbp-38h] BYREF
socklen_t len; // [rsp+920h] [rbp-28h] BYREF
struct sockaddr *v13; // [rsp+928h] [rbp-20h]

v13 = v5;
len = 128;
getsockname(a1, v5, &len);
v10 = a2;
v9 = 16;
v2 = func1(s, 0x423uLL, (__int64)v8);
v3 = func1(v7, 0x423uLL, (__int64)v11);
return fprintf(stderr, "UDP local %s remote %s\n", v3, v2);
}

original_code:
void print_udp_xchange(int sockfd, struct sockaddr* addr, socklen_t addrlen)
{
    struct addrinfo src_addrinfo, to_addrinfo;
    char str_addr[1025 +1+32 +1];
    char str_addr2[1025 +1+32 +1];
    struct sockaddr_storage ss;
    src_addrinfo.ai_addr = (struct sockaddr*)&ss;
    src_addrinfo.ai_addrlen = sizeof(ss);
    getsockname(sockfd, src_addrinfo.ai_addr, &src_addrinfo.ai_addrlen);
    to_addrinfo.ai_addr = addr;
    to_addrinfo.ai_addrlen = sizeof(*addr);
    fprintf(stderr, "UDP local %s remote %s\n",
            sprintaddr(str_addr, sizeof(str_addr), &src_addrinfo),
            sprintaddr(str_addr2, sizeof(str_addr2), &to_addrinfo)
           );
}

canonical_original_code:
void print_udp_xchange(int sockfd, struct sockaddr *addr, unsigned int addrlen)
{
    struct addrinfo src_addrinfo; struct addrinfo to_addrinfo;
    char str_addr[-1];
    char str_addr2[-1];
    struct sockaddr_storage ss;
    src_addrinfo.ai_addr = (struct sockaddr *)&ss;
    src_addrinfo.ai_addrlen = sizeof(ss);
    getsockname(sockfd, src_addrinfo.ai_addr, &src_addrinfo.ai_addrlen);
    to_addrinfo.ai_addr = addr;
    to_addrinfo.ai_addrlen = sizeof(*addr);
    fprintf(stderr, "UDP local %s remote %s\n",
            sprintaddr(str_addr, sizeof(str_addr), &src_addrinfo),
            sprintaddr(str_addr2, sizeof(str_addr2), &to_addrinfo)
           );
}

variable_types: sockfd int

variable_types:
addrlen
unsigned int

variable_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }

variable_types: struct sockaddr_storage { unsigned short ss_family; char __ss_padding[-1]; unsigned long __ss_align; }

user_defined_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }


decompiled_code:
void __fastcall __noreturn udp_echo(int *a1)
{
const char *v1; // rbp
size_t v2; // r12
ssize_t v3; // rax
size_t v4; // r14
socklen_t addr_len; // [rsp+Ch] [rbp-1003Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-10038h] BYREF
char s[65576]; // [rsp+20h] [rbp-10028h] BYREF

memset(s, 0, 0x10000uLL);
v1 = (const char *)*(&cfg + 1);
v2 = strlen(v1);
memcpy(s, v1, v2);
while ( 1 )
{
do
{
addr_len = 16;
v3 = recvfrom(*a1, &s[v2], 0x10000 - v2, 0, &addr, &addr_len);
v4 = v2 + v3;
s[v2 + v3] = 0;
fprintf(stderr, "%ld: %s\n", v3, &s[v2]);
print_udp_xchange(*a1, (__int64)&addr);
}
while ( (int)sendto(*a1, s, v4, 0, &addr, addr_len) >= 0 );
perror("sendto");
}
}

canonical_decompiled_code:
void __fastcall __noreturn func4(int *a1)
{
const char *v1; // rbp
size_t v2; // r12
ssize_t v3; // rax
size_t v4; // r14
socklen_t addr_len; // [rsp+Ch] [rbp-1003Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-10038h] BYREF
char s[65576]; // [rsp+20h] [rbp-10028h] BYREF

memset(s, 0, 0x10000uLL);
v1 = (const char *)*(&cfg + 1);
v2 = strlen(v1);
memcpy(s, v1, v2);
while ( 1 )
{
do
{
addr_len = 16;
v3 = recvfrom(*a1, &s[v2], 0x10000 - v2, 0, &addr, &addr_len);
v4 = v2 + v3;
s[v2 + v3] = 0;
fprintf(stderr, "%ld: %s\n", v3, &s[v2]);
func3(*a1, (__int64)&addr);
}
while ( (int)sendto(*a1, s, v4, 0, &addr, addr_len) >= 0 );
perror("sendto");
}
}

original_code:
void udp_echo(struct listen_endpoint* listen_socket)
{
    char data[65536];
    struct sockaddr src_addr;
    socklen_t addrlen;
    memset(data, 0, sizeof(data));
    size_t prefix_len = strlen(cfg.prefix);
    memcpy(data, cfg.prefix, prefix_len);
    while (1) {
        addrlen = sizeof(src_addr);
        size_t len = recvfrom(listen_socket->socketfd,
                           data + prefix_len,
                           sizeof(data) - prefix_len,
                           0,
                           &src_addr,
                           &addrlen);
        if (len < 0) {
            perror("recvfrom");
        }
        *(data + prefix_len + len) = 0;
        fprintf(stderr, "%ld: %s\n", len, data + prefix_len);
        print_udp_xchange(listen_socket->socketfd, &src_addr, addrlen);
        int res = sendto(listen_socket->socketfd,
                         data,
                         len + prefix_len,
                         0,
                         &src_addr,
                         addrlen);
        if (res < 0) {
            perror("sendto");
        }
    }
}

canonical_original_code:
void udp_echo(struct listen_endpoint *listen_socket)
{
    char data[65536];
    struct sockaddr src_addr;
    unsigned int addrlen;
    memset(data, 0, sizeof(data));
    unsigned long prefix_len = strlen(cfg.prefix);
    memcpy(data, cfg.prefix, prefix_len);
    while (1) {
        addrlen = sizeof(src_addr);
        unsigned long len = recvfrom(listen_socket->socketfd,
                           data + prefix_len,
                           sizeof(data) - prefix_len,
                           0,
                           &src_addr,
                           &addrlen);
        if (len < 0) {
            perror("recvfrom");
        }
        *(data + prefix_len + len) = 0;
        fprintf(stderr, "%ld: %s\n", len, data + prefix_len);
        print_udp_xchange(listen_socket->socketfd, &src_addr, addrlen);
        int res = sendto(listen_socket->socketfd,
                         data,
                         len + prefix_len,
                         0,
                         &src_addr,
                         addrlen);
        if (res < 0) {
            perror("sendto");
        }
    }
}

variable_types:
data
char [65536]

variable_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; }

variable_types:
len
unsigned long

user_defined_types: struct listen_endpoint { int socketfd; int type; }


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
__int64 v5; // [rsp+8h] [rbp-10h] BYREF

cfg = 0LL;
*(&cfg + 1) = 0LL;
*(&cfg + 2) = 0LL;
*(&cfg + 3) = 0LL;
if ( (unsigned int)echocfg_cl_parse(argc, argv, &cfg) )
exit(1);
echocfg_fprint(stdout, &cfg, 0LL);
v3 = start_listen_sockets((void **)&v5);
main_loop(v5, v3);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
__int64 v5; // [rsp+8h] [rbp-10h] BYREF

cfg = 0LL;
*(&cfg + 1) = 0LL;
*(&cfg + 2) = 0LL;
*(&cfg + 3) = 0LL;
if ( (unsigned int)echocfg_cl_parse(argc, argv, &cfg) )
exit(1);
echocfg_fprint(stdout, &cfg, 0LL);
v3 = func8((void **)&v5);
func5(v5, v3);
return 0;
}

original_code:
int main(int argc, char *argv[])
{
   extern char *optarg;
   extern int optind;
   int num_addr_listen;
   struct listen_endpoint *listen_sockets;
   memset(&cfg, 0, sizeof(cfg));
   if (echocfg_cl_parse(argc, argv, &cfg))
       exit(1);
   echocfg_fprint(stdout, &cfg, 0);
   num_addr_listen = start_listen_sockets(&listen_sockets);
   main_loop(listen_sockets, num_addr_listen);
   return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
optarg
char *

variable_types: optind int

return_type: int


sprintaddr

decompiled_code:
char *__fastcall sprintaddr(char *s, size_t maxlen, __int64 a3)
{
char serv[2]; // [rsp+8h] [rbp-448h] BYREF
char host[2]; // [rsp+28h] [rbp-428h] BYREF

if ( getnameinfo(*(const struct sockaddr **)(a3 + 24), *(_DWORD *)(a3 + 16), host, 0x401u, serv, 0x20u, 0)
&& getnameinfo(*(const struct sockaddr **)(a3 + 24), *(_DWORD *)(a3 + 16), host, 0x401u, serv, 0x20u, 3) )
{
strcpy(host, "?");
strcpy(serv, "?");
}
snprintf(s, maxlen, "%s:%s", host, serv);
return s;
}

canonical_decompiled_code:
char *__fastcall func1(char *s, size_t maxlen, __int64 a3)
{
char serv[2]; // [rsp+8h] [rbp-448h] BYREF
char host[2]; // [rsp+28h] [rbp-428h] BYREF

if ( getnameinfo(*(const struct sockaddr **)(a3 + 24), *(_DWORD *)(a3 + 16), host, 0x401u, serv, 0x20u, 0)
&& getnameinfo(*(const struct sockaddr **)(a3 + 24), *(_DWORD *)(a3 + 16), host, 0x401u, serv, 0x20u, 3) )
{
strcpy(host, "?");
strcpy(serv, "?");
}
snprintf(s, maxlen, "%s:%s", host, serv);
return s;
}

original_code:
char* sprintaddr(char* buf, size_t size, struct addrinfo *a)
{
   char host[1025], serv[32];
   int res;
   res = getnameinfo(a->ai_addr, a->ai_addrlen,
               host, sizeof(host),
               serv, sizeof(serv),
               0 );
   if (res) {
       res = getnameinfo(a->ai_addr, a->ai_addrlen,
                         host, sizeof(host),
                         serv, sizeof(serv),
                         1 | 2);
       if (res) {
           strcpy(host, "?");
           strcpy(serv, "?");
       }
   }
   snprintf(buf, size, "%s:%s", host, serv);
   return buf;
}

canonical_original_code:
char *sprintaddr(char *buf, unsigned long size, struct addrinfo *a)
{
   char host[1025]; char serv[32];
   int res;
   res = getnameinfo(a->ai_addr, a->ai_addrlen,
               host, sizeof(host),
               serv, sizeof(serv),
               0 );
   if (res) {
       res = getnameinfo(a->ai_addr, a->ai_addrlen,
                         host, sizeof(host),
                         serv, sizeof(serv),
                         1 | 2);
       if (res) {
           strcpy(host, "?");
           strcpy(serv, "?");
       }
   }
   snprintf(buf, size, "%s:%s", host, serv);
   return buf;
}

variable_types:
buf
char *

variable_types:
size
unsigned long

variable_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *

variable_types:
host
char [1025]

variable_types:
serv
char [32]

return_type: char *


decompiled_code:
void __fastcall check_res_dump(int a1, __int64 a2, const char *a3)
{
__int64 v3; // rbx
__int64 v4; // rbp
__int64 v5; // r12
int *v7; // rax
char *v8; // r12
char *v9; // rax
char v10; // [rsp-428h] [rbp-428h] BYREF
__int64 v11; // [rsp-18h] [rbp-18h]
__int64 v12; // [rsp-10h] [rbp-10h]
__int64 v13; // [rsp-8h] [rbp-8h]

if ( a1 == -1 )
{
v13 = v5;
v12 = v4;
v11 = v3;
if ( a2 )
{
v7 = _errno_location();
v8 = strerror(*v7);
v9 = sprintaddr(&v10, 0x401uLL, a2);
fprintf(stderr, "error %s:%s: %s\n", v9, a3, v8);
}
else
{
fwrite("Dying just because\n", 1uLL, 0x13uLL, stderr);
}
exit(1);
}
}

canonical_decompiled_code:
void __fastcall func2(int a1, __int64 a2, const char *a3)
{
__int64 v3; // rbx
__int64 v4; // rbp
__int64 v5; // r12
int *v7; // rax
char *v8; // r12
char *v9; // rax
char v10; // [rsp-428h] [rbp-428h] BYREF
__int64 v11; // [rsp-18h] [rbp-18h]
__int64 v12; // [rsp-10h] [rbp-10h]
__int64 v13; // [rsp-8h] [rbp-8h]

if ( a1 == -1 )
{
v13 = v5;
v12 = v4;
v11 = v3;
if ( a2 )
{
v7 = _errno_location();
v8 = strerror(*v7);
v9 = func1(&v10, 0x401uLL, a2);
fprintf(stderr, "error %s:%s: %s\n", v9, a3, v8);
}
else
{
fwrite("Dying just because\n", 1uLL, 0x13uLL, stderr);
}
exit(1);
}
}

original_code:
void check_res_dump(int res, struct addrinfo *addr, char* syscall)
{
    char buf[1025];
    if (res == -1) {
        if (addr)
            fprintf(stderr, "error %s:%s: %s\n",
                    sprintaddr(buf, sizeof(buf), addr),
                    syscall,
                    strerror((*__errno_location ())));
        else
            fprintf(stderr, "Dying just because\n");
        exit(1);
    }
}

canonical_original_code:
void check_res_dump(int res, struct addrinfo *addr, char *syscall)
{
    char buf[1025];
    if (res == -1) {
        if (addr)
            fprintf(stderr, "error %s:%s: %s\n",
                    sprintaddr(buf, sizeof(buf), addr),
                    syscall,
                    strerror((*__errno_location ())));
        else
            fprintf(stderr, "Dying just because\n");
        exit(1);
    }
}

variable_types: res int

variable_types:
syscall
char *

variable_types:
buf
char [1025]

user_defined_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; }


decompiled_code:
__pid_t __fastcall main_loop(__int64 a1, int a2)
{
int i; // ebx

if ( a2 > 0 )
{
for ( i = 0; i != a2; ++i )
{
if ( !fork() )
{
if ( (_DWORD)cfg )
udp_echo((int *)(a1 + 8LL * i));
tcp_echo((int *)(a1 + 8LL * i));
}
}
}
return wait(0LL);
}

canonical_decompiled_code:
__pid_t __fastcall func5(__int64 a1, int a2)
{
int i; // ebx

if ( a2 > 0 )
{
for ( i = 0; i != a2; ++i )
{
if ( !fork() )
{
if ( (_DWORD)cfg )
func4((int *)(a1 + 8LL * i));
func0((int *)(a1 + 8LL * i));
}
}
}
return wait(0LL);
}

original_code:
void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
{
    int i;
    for (i = 0; i < num_addr_listen; i++) {
        if (!fork()) {
            if (cfg.udp) {
                udp_echo(&listen_sockets[i]);
            } else {
                tcp_echo(&listen_sockets[i]);
            }
        }
    }
    wait(((void *)0));
}

variable_types: struct listen_endpoint { int socketfd; int type; } []

variable_types: i int


decompiled_code:
__int64 __fastcall listen_single_addr(__int64 a1, __int64 a2, int a3)
{
unsigned int v4; // ebp
int v5; // eax
int v6; // eax
int v8; // eax
int v9; // eax
int optval[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v4 = socket(**(unsigned __int16 **)(a1 + 24), 1 - ((a3 == 0) - 1), 0);
check_res_dump(v4, a1, "socket");
optval[0] = 1;
v5 = setsockopt(v4, 1, 2, optval, 4u);
check_res_dump(v5, a1, "setsockopt(SO_REUSEADDR)");
if ( **(_WORD **)(a1 + 24) == 10 )
{
v8 = setsockopt(v4, 41, 26, optval, 4u);
check_res_dump(v8, a1, "setsockopt(IPV6_V6ONLY)");
}
v6 = bind(v4, *(const struct sockaddr **)(a1 + 24), *(_DWORD *)(a1 + 16));
check_res_dump(v6, a1, "bind");
if ( !a3 )
{
v9 = listen(v4, 50);
check_res_dump(v9, a1, "listen");
}
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2, int a3)
{
unsigned int v4; // ebp
int v5; // eax
int v6; // eax
int v8; // eax
int v9; // eax
int optval[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v4 = socket(**(unsigned __int16 **)(a1 + 24), 1 - ((a3 == 0) - 1), 0);
func2(v4, a1, "socket");
optval[0] = 1;
v5 = setsockopt(v4, 1, 2, optval, 4u);
func2(v5, a1, "setsockopt(SO_REUSEADDR)");
if ( **(_WORD **)(a1 + 24) == 10 )
{
v8 = setsockopt(v4, 41, 26, optval, 4u);
func2(v8, a1, "setsockopt(IPV6_V6ONLY)");
}
v6 = bind(v4, *(const struct sockaddr **)(a1 + 24), *(_DWORD *)(a1 + 16));
func2(v6, a1, "bind");
if ( !a3 )
{
v9 = listen(v4, 50);
func2(v9, a1, "listen");
}
return v4;
}

original_code:
int listen_single_addr(struct addrinfo* addr, int keepalive, int udp)
{
    struct sockaddr_storage *saddr;
    int sockfd, one, res;
    saddr = (struct sockaddr_storage*)addr->ai_addr;
    sockfd = socket(saddr->ss_family, udp ? SOCK_DGRAM : SOCK_STREAM, 0);
    check_res_dump(sockfd, addr, "socket");
    one = 1;
    res = setsockopt(sockfd, 1, 2, (char*)&one, sizeof(one));
    check_res_dump(res, addr, "setsockopt(SO_REUSEADDR)");
    if (addr->ai_addr->sa_family == 10) {
        res = setsockopt(sockfd, IPPROTO_IPV6, 26, (char*)&one, sizeof(one));
        check_res_dump(res, addr, "setsockopt(IPV6_V6ONLY)");
    }
    res = bind(sockfd, addr->ai_addr, addr->ai_addrlen);
    check_res_dump(res, addr, "bind");
    if (!udp) {
        res = listen (sockfd, 50);
        check_res_dump(res, addr, "listen");
    }
    return sockfd;
}

canonical_original_code:
int listen_single_addr(struct addrinfo *addr, int keepalive, int udp)
{
    struct sockaddr_storage *saddr;
    int sockfd; int one; int res;
    saddr = (struct sockaddr_storage *)addr->ai_addr;
    sockfd = socket(saddr->ss_family, udp ? SOCK_DGRAM : SOCK_STREAM, 0);
    check_res_dump(sockfd, addr, "socket");
    one = 1;
    res = setsockopt(sockfd, 1, 2, (char *)&one, sizeof(one));
    check_res_dump(res, addr, "setsockopt(SO_REUSEADDR)");
    if (addr->ai_addr->sa_family == 10) {
        res = setsockopt(sockfd, IPPROTO_IPV6, 26, (char *)&one, sizeof(one));
        check_res_dump(res, addr, "setsockopt(IPV6_V6ONLY)");
    }
    res = bind(sockfd, addr->ai_addr, addr->ai_addrlen);
    check_res_dump(res, addr, "bind");
    if (!udp) {
        res = listen (sockfd, 50);
        check_res_dump(res, addr, "listen");
    }
    return sockfd;
}

variable_types: keepalive int

variable_types: udp int

variable_types: struct sockaddr_storage { unsigned short ss_family; char __ss_padding[-1]; unsigned long __ss_align; } *

variable_types: sockfd int

variable_types: one int


decompiled_code:
__int64 __fastcall resolve_split_name(struct addrinfo **pai, char *name, char *service)
{
char *v3; // rbx
char *v5; // rax
int v6; // eax
unsigned int v7; // ebp
const char *v9; // rax
struct addrinfo v10; // [rsp+0h] [rbp-48h] BYREF

v3 = name;
*(_QWORD *)&v10.ai_flags = 0LL;
*(_QWORD *)&v10.ai_socktype = 1LL;
*(_QWORD *)&v10.ai_addrlen = 0LL;
v10.ai_addr = 0LL;
v10.ai_canonname = 0LL;
v10.ai_next = 0LL;
if ( *name == 91 )
{
v5 = strrchr(name, 93);
if ( !v5 )
{
fprintf(stderr, "%s: no closing bracket in IPv6 address?\n", name);
return (unsigned int)-1;
}
v3 = name + 1;
*v5 = 0;
}
v6 = getaddrinfo(v3, service, &v10, pai);
v7 = v6;
if ( v6 )
{
v9 = gai_strerror(v6);
fprintf(stderr, "%s `%s:%s'\n", v9, v3, service);
}
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func7(struct addrinfo **pai, char *name, char *service)
{
char *v3; // rbx
char *v5; // rax
int v6; // eax
unsigned int v7; // ebp
const char *v9; // rax
struct addrinfo v10; // [rsp+0h] [rbp-48h] BYREF

v3 = name;
*(_QWORD *)&v10.ai_flags = 0LL;
*(_QWORD *)&v10.ai_socktype = 1LL;
*(_QWORD *)&v10.ai_addrlen = 0LL;
v10.ai_addr = 0LL;
v10.ai_canonname = 0LL;
v10.ai_next = 0LL;
if ( *name == 91 )
{
v5 = strrchr(name, 93);
if ( !v5 )
{
fprintf(stderr, "%s: no closing bracket in IPv6 address?\n", name);
return (unsigned int)-1;
}
v3 = name + 1;
*v5 = 0;
}
v6 = getaddrinfo(v3, service, &v10, pai);
v7 = v6;
if ( v6 )
{
v9 = gai_strerror(v6);
fprintf(stderr, "%s `%s:%s'\n", v9, v3, service);
}
return v7;
}

original_code:
int resolve_split_name(struct addrinfo **out, char* host, char* serv)
{
   struct addrinfo hint;
   char *end;
   int res;
   memset(&hint, 0, sizeof(hint));
   hint.ai_family = 0;
   hint.ai_socktype = SOCK_STREAM;
   if (host[0] == '[') {
       end = strrchr(host, ']');
       if (!end) {
           fprintf(stderr, "%s: no closing bracket in IPv6 address?\n", host);
           return -1;
       }
       host++;
       *end = 0;
   }
   res = getaddrinfo(host, serv, &hint, out);
   if (res)
      fprintf(stderr, "%s `%s:%s'\n", gai_strerror(res), host, serv);
   return res;
}

canonical_original_code:
int resolve_split_name(struct addrinfo **out, char *host, char *serv)
{
   struct addrinfo hint;
   char *end;
   int res;
   memset(&hint, 0, sizeof(hint));
   hint.ai_family = 0;
   hint.ai_socktype = SOCK_STREAM;
   if (host[0] == '[') {
       end = strrchr(host, ']');
       if (!end) {
           fprintf(stderr, "%s: no closing bracket in IPv6 address?\n", host);
           return -1;
       }
       host++;
       *end = 0;
   }
   res = getaddrinfo(host, serv, &hint, out);
   if (res)
      fprintf(stderr, "%s `%s:%s'\n", gai_strerror(res), host, serv);
   return res;
}

variable_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } **

variable_types:
host
char *

variable_types:
serv
char *

variable_types:
end
char *


decompiled_code:
__int64 __fastcall start_listen_sockets(void **a1)
{
unsigned int v1; // er15
struct addrinfo *v2; // rbp
size_t v3; // r12
char *v4; // rax
char *v5; // rax
int v7; // [rsp+0h] [rbp-458h]
unsigned __int64 v8; // [rsp+8h] [rbp-450h]
char s[1032]; // [rsp+10h] [rbp-448h] BYREF
struct addrinfo *ai; // [rsp+418h] [rbp-40h] BYREF

*a1 = 0LL;
fwrite("Listening to:\n", 1uLL, 0xEuLL, stderr);
if ( !*(&cfg + 2) )
return 0;
v8 = 0LL;
v1 = 0;
do
{
v7 = cfg;
if ( (unsigned int)resolve_split_name(&ai, *(char **)(*(&cfg + 3) + 16 * v8), *(char **)(*(&cfg + 3) + 16 * v8 + 8)) )
exit(4);
v2 = ai;
if ( ai )
{
v3 = 8LL * (int)v1 + 8;
do
{
++v1;
v4 = (char *)realloc(*a1, v3);
*a1 = v4;
*(_DWORD *)&v4[v3 - 8] = listen_single_addr((__int64)v2, 0LL, v7);
*(_DWORD *)((char *)*a1 + v3 - 4) = 2 - (v7 == 0);
v5 = sprintaddr(s, 0x401uLL, (__int64)v2);
fprintf(stderr, "%d:\t%s\n", *(unsigned int *)((char *)*a1 + v3 - 8), v5);
v2 = v2->ai_next;
v3 += 8LL;
}
while ( v2 );
}
freeaddrinfo(ai);
++v8;
}
while ( *(&cfg + 2) > v8 );
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func8(void **a1)
{
unsigned int v1; // er15
struct addrinfo *v2; // rbp
size_t v3; // r12
char *v4; // rax
char *v5; // rax
int v7; // [rsp+0h] [rbp-458h]
unsigned __int64 v8; // [rsp+8h] [rbp-450h]
char s[1032]; // [rsp+10h] [rbp-448h] BYREF
struct addrinfo *ai; // [rsp+418h] [rbp-40h] BYREF

*a1 = 0LL;
fwrite("Listening to:\n", 1uLL, 0xEuLL, stderr);
if ( !*(&cfg + 2) )
return 0;
v8 = 0LL;
v1 = 0;
do
{
v7 = cfg;
if ( (unsigned int)func7(&ai, *(char **)(*(&cfg + 3) + 16 * v8), *(char **)(*(&cfg + 3) + 16 * v8 + 8)) )
exit(4);
v2 = ai;
if ( ai )
{
v3 = 8LL * (int)v1 + 8;
do
{
++v1;
v4 = (char *)realloc(*a1, v3);
*a1 = v4;
*(_DWORD *)&v4[v3 - 8] = func6((__int64)v2, 0LL, v7);
*(_DWORD *)((char *)*a1 + v3 - 4) = 2 - (v7 == 0);
v5 = func1(s, 0x401uLL, (__int64)v2);
fprintf(stderr, "%d:\t%s\n", *(unsigned int *)((char *)*a1 + v3 - 8), v5);
v2 = v2->ai_next;
v3 += 8LL;
}
while ( v2 );
}
freeaddrinfo(ai);
++v8;
}
while ( *(&cfg + 2) > v8 );
return v1;
}

original_code:
int start_listen_sockets(struct listen_endpoint *sockfd[])
{
    struct addrinfo *addr, *start_addr;
    char buf[1025];
    int i, res;
    int num_addr = 0, keepalive = 0, udp = 0;
    *sockfd = ((void *)0);
    fprintf(stderr, "Listening to:\n");
    for (i = 0; i < cfg.listen_len; i++) {
        udp = cfg.udp;
        res = resolve_split_name(&start_addr, cfg.listen[i].host, cfg.listen[i].port);
        if (res) exit(4);
        for (addr = start_addr; addr; addr = addr->ai_next) {
            num_addr++;
            *sockfd = realloc(*sockfd, num_addr * sizeof(*sockfd));
            (*sockfd)[num_addr-1].socketfd = listen_single_addr(addr, keepalive, udp);
            (*sockfd)[num_addr-1].type = udp ? SOCK_DGRAM : SOCK_STREAM;
            fprintf(stderr, "%d:\t%s\n", (*sockfd)[num_addr-1].socketfd, sprintaddr(buf, sizeof(buf), addr));
        }
        freeaddrinfo(start_addr);
    }
    return num_addr;
}

canonical_original_code:
int start_listen_sockets(struct listen_endpoint *sockfd[])
{
    struct addrinfo *addr; struct addrinfo *start_addr;
    char buf[1025];
    int i; int res;
    int num_addr = 0; int keepalive = 0; int udp = 0;
    *sockfd = ((void *)0);
    fprintf(stderr, "Listening to:\n");
    for (i = 0; i < cfg.listen_len; i++) {
        udp = cfg.udp;
        res = resolve_split_name(&start_addr, cfg.listen[i].host, cfg.listen[i].port);
        if (res) exit(4);
        for (addr = start_addr; addr; addr = addr->ai_next) {
            num_addr++;
            *sockfd = realloc(*sockfd, num_addr * sizeof(*sockfd));
            (*sockfd)[num_addr-1].socketfd = listen_single_addr(addr, keepalive, udp);
            (*sockfd)[num_addr-1].type = udp ? SOCK_DGRAM : SOCK_STREAM;
            fprintf(stderr, "%d:\t%s\n", (*sockfd)[num_addr-1].socketfd, sprintaddr(buf, sizeof(buf), addr));
        }
        freeaddrinfo(start_addr);
    }
    return num_addr;
}

variable_types: struct listen_endpoint { int socketfd; int type; } *[]

variable_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *


decompiled_code:
__int64 __fastcall hash_find_index(__int64 a1, __int64 a2)
{
unsigned int v2; // ebx
__int64 v3; // rax
__int64 v4; // rbp
int i; // er14

v2 = hash_make_key(a1, a2);
v3 = gap_get(*(_QWORD *)(a1 + 8), v2);
if ( !v3 )
return (unsigned int)-1;
v4 = v3;
for ( i = 0; *(_DWORD *)a1 >= i; ++i )
{
if ( !(*(unsigned int (__fastcall **)(__int64, __int64))(a1 + 24))(v4, a2) )
return v2;
v2 = hash_next_index((_DWORD *)a1, v2);
v4 = gap_get(*(_QWORD *)(a1 + 8), v2);
if ( !v4 )
return (unsigned int)-1;
}
return (unsigned int)-1;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2)
{
unsigned int v2; // ebx
__int64 v3; // rax
__int64 v4; // rbp
int i; // er14

v2 = func1(a1, a2);
v3 = func0(*(_QWORD *)(a1 + 8), v2);
if ( !v3 )
return (unsigned int)-1;
v4 = v3;
for ( i = 0; *(_DWORD *)a1 >= i; ++i )
{
if ( !(*(unsigned int (__fastcall **)(__int64, __int64))(a1 + 24))(v4, a2) )
return v2;
v2 = func2((_DWORD *)a1, v2);
v4 = func0(*(_QWORD *)(a1 + 8), v2);
if ( !v4 )
return (unsigned int)-1;
}
return (unsigned int)-1;
}

original_code:
static int hash_find_index(hash* h, hash_item item)
{
    hash_item cnx;
    int index = hash_make_key(h, item);
    int cnt = 0;
    cnx = gap_get(h->data, index);
    while (cnx != FREE) {
        if (cnt++ > h->hash_size) return -1;
        if (!h->cmp_item(cnx, item))
            break;
        index = hash_next_index(h, index);
        cnx = gap_get(h->data, index);
    }
    if (cnx == FREE) return -1;
    return index;
}

canonical_original_code:
static int hash_find_index(struct hash *h, void *item)
{
    void *cnx;
    int index = hash_make_key(h, item);
    int cnt = 0;
    cnx = gap_get(h->data, index);
    while (cnx != FREE) {
        if (cnt++ > h->hash_size) return -1;
        if (!h->cmp_item(cnx, item))
            break;
        index = hash_next_index(h, index);
        cnx = gap_get(h->data, index);
    }
    if (cnx == FREE) return -1;
    return index;
}

variable_types: struct hash { int hash_size; int item_cnt; struct gap_array { int len; void **array; } *data; int (*hash_make_key)(void *item); int (*cmp_item)(void *item1, void *item2); } *

variable_types:
item
void *

variable_types:
cnx
void *

variable_types: index int

variable_types: cnt int

user_defined_types: struct hash { int hash_size; int item_cnt; struct gap_array *data; int (*hash_make_key)(void *item); int (*cmp_item)(void *item1, void *item2); }


distance

decompiled_code:
__int64 __fastcall distance(int a1, _DWORD *a2, __int64 a3)
{
int v3; // eax
__int64 result; // rax

v3 = hash_make_key((__int64)a2, a3);
if ( v3 > a1 )
result = (unsigned int)(*a2 + a1 - v3);
else
result = (unsigned int)(a1 - v3);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(int a1, _DWORD *a2, __int64 a3)
{
int v3; // eax
__int64 result; // rax

v3 = func1((__int64)a2, a3);
if ( v3 > a1 )
result = (unsigned int)(*a2 + a1 - v3);
else
result = (unsigned int)(a1 - v3);
return result;
}

original_code:
static int distance(int current_index, hash* h, hash_item item)
{
    int wanted_index = hash_make_key(h, item);
    if (wanted_index <= current_index)
        return current_index - wanted_index;
    else
        return current_index - wanted_index + h->hash_size;
}

canonical_original_code:
static int distance(int current_index, struct hash *h, void *item)
{
    int wanted_index = hash_make_key(h, item);
    if (wanted_index <= current_index)
        return current_index - wanted_index;
    else
        return current_index - wanted_index + h->hash_size;
}

user_defined_types: struct gap_array { int len; void **array; }


decompiled_code:
__int64 __fastcall hash_find(__int64 a1, __int64 a2)
{
int v2; // eax
__int64 result; // rax

v2 = hash_find_index(a1, a2);
if ( v2 == -1 )
result = 0LL;
else
result = gap_get(*(_QWORD *)(a1 + 8), v2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2)
{
int v2; // eax
__int64 result; // rax

v2 = func3(a1, a2);
if ( v2 == -1 )
result = 0LL;
else
result = func0(*(_QWORD *)(a1 + 8), v2);
return result;
}

original_code:
hash_item hash_find(hash* h, hash_item item)
{
    int index = hash_find_index(h, item);
    if (index == -1) return ((void *)0);
    hash_item out = gap_get(h->data, index);
    return out;
}

canonical_original_code:
void *hash_find(struct hash *h, void *item)
{
    int index = hash_find_index(h, item);
    if (index == -1) return ((void *)0);
    void *out = gap_get(h->data, index);
    return out;
}

variable_types:
out
void *

return_type: void *


decompiled_code:
__int64 __fastcall hash_insert(__int64 a1, __int64 a2)
{
__int64 v2; // r13
int v3; // ebx
__int64 v4; // r14
__int64 i; // rbp
int v7; // er15

v2 = a2;
v3 = hash_make_key(a1, a2);
v4 = *(_QWORD *)(a1 + 8);
if ( *(_DWORD *)(a1 + 4) == *(_DWORD *)a1 )
return 0xFFFFFFFFLL;
for ( i = gap_get(*(_QWORD *)(a1 + 8), v3); i; i = gap_get(v4, v3) )
{
v7 = distance(v3, (_DWORD *)a1, i);
if ( v7 < (int)distance(v3, (_DWORD *)a1, v2) )
{
gap_set(*(_QWORD *)(a1 + 8), v3, v2);
v2 = i;
}
v3 = hash_next_index((_DWORD *)a1, v3);
}
gap_set(v4, v3, v2);
++*(_DWORD *)(a1 + 4);
return 0LL;
}

original_code:
int hash_insert(hash* h, hash_item new)
{
    int bubble_wanted_index = hash_make_key(h, new);
    int index = bubble_wanted_index;
    gap_array* hash = h->data;
    if (h->item_cnt == h->hash_size)
        return -1;
    hash_item curr_item = gap_get(hash, index);
    while (curr_item) {
        if (distance(index, h, curr_item) < distance(index, h, new)) {
            gap_set(h->data, index, new);
            new = curr_item;
        }
        index = hash_next_index(h, index);
        curr_item = gap_get(hash, index);
    }
    gap_set(hash, index, new);
    h->item_cnt++;
    return 0;
}

canonical_original_code:
int hash_insert(struct hash *h, void *new)
{
    int bubble_wanted_index = hash_make_key(h, new);
    int index = bubble_wanted_index;
    struct gap_array *hash = h->data;
    if (h->item_cnt == h->hash_size)
        return -1;
    void *curr_item = gap_get(hash, index);
    while (curr_item) {
        if (distance(index, h, curr_item) < distance(index, h, new)) {
            gap_set(h->data, index, new);
            new = curr_item;
        }
        index = hash_next_index(h, index);
        curr_item = gap_get(hash, index);
    }
    gap_set(hash, index, new);
    h->item_cnt++;
    return 0;
}

variable_types:
new
void *

variable_types: struct gap_array { int len; void **array; } *


decompiled_code:
__int64 __fastcall hash_remove(__int64 a1, __int64 a2)
{
__int64 v2; // r14
unsigned int v3; // ebx
int v4; // er12
__int64 v5; // rax
__int64 v6; // rbp

v2 = *(_QWORD *)(a1 + 8);
v3 = hash_find_index(a1, a2);
if ( v3 != -1 )
{
while ( 1 )
{
v4 = hash_next_index((_DWORD *)a1, v3);
v5 = gap_get(*(_QWORD *)(a1 + 8), v4);
v6 = v5;
if ( !v5 || !(unsigned int)distance(v4, (_DWORD *)a1, v5) )
break;
gap_set(v2, v3, v6);
v3 = hash_next_index((_DWORD *)a1, v3);
}
--*(_DWORD *)(a1 + 4);
gap_set(v2, v3, 0LL);
v3 = 0;
}
return v3;
}

original_code:
int hash_remove(hash* h, hash_item item)
{
    gap_array* hash = h->data;
    int index = hash_find_index(h, item);
    if (index == -1) return -1;
    while (1) {
        int next_index = hash_next_index(h, index);
        hash_item next = gap_get(h->data, next_index);
        if ((next == FREE) || (distance(next_index, h, next) == 0)) {
            h->item_cnt--;
            gap_set(hash, index, FREE);
            return 0;
        }
        gap_set(hash, index, next);
        index = hash_next_index(h, index);;
    }
    return 0;
}

canonical_original_code:
int hash_remove(struct hash *h, void *item)
{
    struct gap_array *hash = h->data;
    int index = hash_find_index(h, item);
    if (index == -1) return -1;
    while (1) {
        int next_index = hash_next_index(h, index);
        void *next = gap_get(h->data, next_index);
        if ((next == FREE) || (distance(next_index, h, next) == 0)) {
            h->item_cnt--;
            gap_set(hash, index, FREE);
            return 0;
        }
        gap_set(hash, index, next);
        index = hash_next_index(h, index);;
    }
    return 0;
}

variable_types:
next
void *


decompiled_code:
void print_message(int pri, _BYTE *a2, const char *a3, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-E0h] BYREF

if ( (*a2 & 1) != 0 && !cfg[13] )
{
va_start(arg, a3);
vfprintf(stderr, a3, arg);
}
if ( (*a2 & 2) != 0 )
{
va_end(arg);
va_start(arg, a3);
vsyslog(pri, a3, arg);
}
if ( (*a2 & 4) != 0 )
{
if ( logfile_fp )
{
va_end(arg);
va_start(arg, a3);
vfprintf(logfile_fp, a3, arg);
fflush(logfile_fp);
}
}
}

canonical_decompiled_code:
void func0(int pri, _BYTE *a2, const char *a3, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-E0h] BYREF

if ( (*a2 & 1) != 0 && !cfg[13] )
{
va_start(arg, a3);
vfprintf(stderr, a3, arg);
}
if ( (*a2 & 2) != 0 )
{
va_end(arg);
va_start(arg, a3);
vsyslog(pri, a3, arg);
}
if ( (*a2 & 4) != 0 )
{
if ( logfile_fp )
{
va_end(arg);
va_start(arg, a3);
vfprintf(logfile_fp, a3, arg);
fflush(logfile_fp);
}
}
}

original_code:
void print_message(msg_info info, const char* str, ...)
{
    va_list ap;
    if ((*info.verbose & 1) && ! cfg.inetd) {
        __builtin_va_start(ap,str);
        vfprintf(stderr, str, ap);
        __builtin_va_end(ap);
    }
    if (*info.verbose & 2) {
        __builtin_va_start(ap,str);
        vsyslog(info.log_level, str, ap);
        __builtin_va_end(ap);
    }
    if (*info.verbose & 4 && logfile_fp != ((void *)0)) {
        __builtin_va_start(ap,str);
        vfprintf(logfile_fp, str, ap);
        fflush(logfile_fp);
        __builtin_va_end(ap);
    }
}

canonical_original_code:
void print_message(struct s_msg_info info, char *str, ...)
{
    __builtin_va_list ap;
    if ((*info.verbose & 1) && ! cfg.inetd) {
        __builtin_va_start(ap,str);
        vfprintf(stderr, str, ap);
        __builtin_va_end(ap);
    }
    if (*info.verbose & 2) {
        __builtin_va_start(ap,str);
        vsyslog(info.log_level, str, ap);
        __builtin_va_end(ap);
    }
    if (*info.verbose & 4 && logfile_fp != ((void *)0)) {
        __builtin_va_start(ap,str);
        vfprintf(logfile_fp, str, ap);
        fflush(logfile_fp);
        __builtin_va_end(ap);
    }
}

variable_types: struct s_msg_info { int log_level; int *verbose; }

variable_types:
str
char *


decompiled_code:
void __fastcall setup_syslog(char *s)
{
char *v1; // r13
unsigned int v2; // ebx
char *v3; // rax
int v4; // ebp
const char *v5; // r12
char **v6; // rbx
char *ptr; // [rsp+0h] [rbp-30h] BYREF

if ( strcmp(*(const char **)&cfg[30], "none") )
{
v1 = strdup(s);
v2 = getpid();
v3 = _xpg_basename(v1);
if ( asprintf(&ptr, "%s[%d]", v3, v2) == -1 )
{
print_message(msg_system_error, *((_BYTE **)&msg_system_error + 1), "%s:%d:", "log.c", 146LL);
perror("asprintf");
exit(1);
}
v4 = *((_DWORD *)&facilitynames + 2);
v5 = *(const char **)&cfg[30];
v6 = &facilitynames;
if ( v4 == -1 )
{
LABEL_6:
fprintf(stderr, "Unknown facility %s\n", *(const char **)&cfg[30]);
exit(1);
}
while ( strcmp(*v6, v5) )
{
v6 += 2;
v4 = *((_DWORD *)v6 + 2);
if ( v4 == -1 )
goto LABEL_6;
}
openlog(ptr, 2, v4);
free(v1);
}
}

canonical_decompiled_code:
void __fastcall func1(char *s)
{
char *v1; // r13
unsigned int v2; // ebx
char *v3; // rax
int v4; // ebp
const char *v5; // r12
char **v6; // rbx
char *ptr; // [rsp+0h] [rbp-30h] BYREF

if ( strcmp(*(const char **)&cfg[30], "none") )
{
v1 = strdup(s);
v2 = getpid();
v3 = _xpg_basename(v1);
if ( asprintf(&ptr, "%s[%d]", v3, v2) == -1 )
{
func0(msg_system_error, *((_BYTE **)&msg_system_error + 1), "%s:%d:", "log.c", 146LL);
perror("asprintf");
exit(1);
}
v4 = *((_DWORD *)&facilitynames + 2);
v5 = *(const char **)&cfg[30];
v6 = &facilitynames;
if ( v4 == -1 )
{
LABEL_6:
fprintf(stderr, "Unknown facility %s\n", *(const char **)&cfg[30]);
exit(1);
}
while ( strcmp(*v6, v5) )
{
v6 += 2;
v4 = *((_DWORD *)v6 + 2);
if ( v4 == -1 )
goto LABEL_6;
}
openlog(ptr, 2, v4);
free(v1);
}
}

original_code:
void setup_syslog(const char* bin_name) {
    char *name1, *name2;
    int res, fn;
    if (!strcmp(cfg.syslog_facility, "none")) {
        do_syslog = 0;
        return;
    }
    name1 = strdup(bin_name);
    res = asprintf(&name2, "%s[%d]", __xpg_basename(name1), getpid());
    if (res == -1) { print_message(msg_system_error, "%s:%d:", "log.c", 146); perror("asprintf"); exit(1); };
    for (fn = 0; facilitynames[fn].c_val != -1; fn++)
        if (strcmp(facilitynames[fn].c_name, cfg.syslog_facility) == 0)
            break;
    if (facilitynames[fn].c_val == -1) {
        fprintf(stderr, "Unknown facility %s\n", cfg.syslog_facility);
        exit(1);
    }
    openlog(name2, 0x02, facilitynames[fn].c_val);
    free(name1);
}

canonical_original_code:
void setup_syslog(char *bin_name) {
    char *name1; char *name2;
    int res; int fn;
    if (!strcmp(cfg.syslog_facility, "none")) {
        do_syslog = 0;
        return;
    }
    name1 = strdup(bin_name);
    res = asprintf(&name2, "%s[%d]", __xpg_basename(name1), getpid());
    if (res == -1) { print_message(msg_system_error, "%s:%d:", "log.c", 146); perror("asprintf"); exit(1); };
    for (fn = 0; facilitynames[fn].c_val != -1; fn++)
        if (strcmp(facilitynames[fn].c_name, cfg.syslog_facility) == 0)
            break;
    if (facilitynames[fn].c_val == -1) {
        fprintf(stderr, "Unknown facility %s\n", cfg.syslog_facility);
        exit(1);
    }
    openlog(name2, 0x02, facilitynames[fn].c_val);
    free(name1);
}

variable_types: res int

variable_types: fn int


decompiled_code:
void setup_logfile()
{
const char *v0; // rdi
int *v1; // rax
char *v2; // rax

v0 = *(const char **)&cfg[34];
if ( v0 )
{
logfile_fp = fopen(v0, "a");
if ( !logfile_fp )
{
v1 = _errno_location();
v2 = strerror(*v1);
fprintf(stderr, "Could not open logfile %s for writing: %s\n", *(const char **)&cfg[34], v2);
exit(1);
}
}
}

canonical_decompiled_code:
void func2()
{
const char *v0; // rdi
int *v1; // rax
char *v2; // rax

v0 = *(const char **)&cfg[34];
if ( v0 )
{
logfile_fp = fopen(v0, "a");
if ( !logfile_fp )
{
v1 = _errno_location();
v2 = strerror(*v1);
fprintf(stderr, "Could not open logfile %s for writing: %s\n", *(const char **)&cfg[34], v2);
exit(1);
}
}
}

original_code:
void setup_logfile()
{
    if (cfg.logfile == ((void *)0))
    {
        return;
    }
    logfile_fp = fopen(cfg.logfile, "a");
    if (logfile_fp == ((void *)0))
    {
        fprintf(stderr, "Could not open logfile %s for writing: %s\n", cfg.logfile, strerror((*__errno_location ())));
        exit(1);
    }
}


decompiled_code:
int close_logfile()
{
int result; // eax

if ( logfile_fp )
{
result = fclose(logfile_fp);
logfile_fp = 0LL;
}
return result;
}

canonical_decompiled_code:
int func3()
{
int result; // eax

if ( logfile_fp )
{
result = fclose(logfile_fp);
logfile_fp = 0LL;
}
return result;
}

original_code:
void close_logfile()
{
    if (logfile_fp != ((void *)0))
    {
        fclose(logfile_fp);
        logfile_fp = ((void *)0);
    }
}


decompiled_code:
void __fastcall log_connection(const char *a1, __int64 a2)
{
const char *v2; // r8
int v3; // eax
_BYTE v4[4248]; // [rsp-1098h] [rbp-1098h] BYREF

if ( *(int *)(*(_QWORD *)(a2 + 8) + 64LL) > 0 )
{
v2 = a1;
if ( a1 || (v3 = get_connection_desc(v4), v2 = v4, v3) )
print_message(
msg_connections,
*((_BYTE **)&msg_connections + 1),
"%s:connection from %s to %s forwarded from %s to %s\n",
**(const char ***)(a2 + 8),
v2,
v2 + 1058,
v2 + 2116,
v2 + 3174);
else
print_message(
msg_connections,
*((_BYTE **)&msg_connections + 1),
"%s: lost incoming connection\n",
**(const char ***)(a2 + 8));
}
}

canonical_decompiled_code:
void __fastcall func4(const char *a1, __int64 a2)
{
const char *v2; // r8
int v3; // eax
_BYTE v4[4248]; // [rsp-1098h] [rbp-1098h] BYREF

if ( *(int *)(*(_QWORD *)(a2 + 8) + 64LL) > 0 )
{
v2 = a1;
if ( a1 || (v3 = get_connection_desc(v4), v2 = v4, v3) )
func0(
msg_connections,
*((_BYTE **)&msg_connections + 1),
"%s:connection from %s to %s forwarded from %s to %s\n",
**(const char ***)(a2 + 8),
v2,
v2 + 1058,
v2 + 2116,
v2 + 3174);
else
func0(
msg_connections,
*((_BYTE **)&msg_connections + 1),
"%s: lost incoming connection\n",
**(const char ***)(a2 + 8));
}
}

original_code:
void log_connection(struct connection_desc* desc, const struct connection *cnx)
{
    struct connection_desc d;
    if (cnx->proto->log_level < 1)
        return;
    if (!desc) {
        desc = &d;
        if (!get_connection_desc(desc, cnx)) {
            print_message(msg_connections, "%s: lost incoming connection\n",
                          cnx->proto->name);
            return;
        }
    }
    print_message(msg_connections, "%s:connection from %s to %s forwarded from %s to %s\n",
                cnx->proto->name,
                desc->peer,
                desc->service,
                desc->local,
                desc->target);
}

canonical_original_code:
void log_connection(struct connection_desc *desc, struct connection *cnx)
{
    struct connection_desc d;
    if (cnx->proto->log_level < 1)
        return;
    if (!desc) {
        desc = &d;
        if (!get_connection_desc(desc, cnx)) {
            print_message(msg_connections, "%s: lost incoming connection\n",
                          cnx->proto->name);
            return;
        }
    }
    print_message(msg_connections, "%s:connection from %s to %s forwarded from %s to %s\n",
                cnx->proto->name,
                desc->peer,
                desc->service,
                desc->local,
                desc->target);
}

variable_types: struct connection_desc { char peer[-1]; } *

variable_types: struct connection { int type; struct sslhcfg_protocols_item { char *name; char *host; char *port; int service_is_present; char *service; int is_udp; int udp_timeout; int fork; int tfo_ok; int transparent; int resolve_on_forward; int log_level; int keepalive; unsigned long sni_hostnames_len; char **sni_hostnames; unsigned long alpn_protocols_len; char **alpn_protocols; unsigned long regex_patterns_len; char **regex_patterns; int minlength_is_present; int minlength; int (*probe)(char *, long, struct sslhcfg_protocols_item *); struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *saddr; void *data; struct dl_list { struct connection *head; struct connection *tail; } timeouts; } *proto; enum connection_state { ST_PROBING=1, ST_SHOVELING=2 } state; long probe_timeout; struct queue { int fd; void *begin_deferred_data; void *deferred_data; int deferred_data_size; } q[2]; struct sockaddr client_addr; unsigned int addrlen; int local_endpoint; long last_active; struct connection *timeout_prev; int target_sock; } *

user_defined_types: struct connection { int type; struct sslhcfg_protocols_item *proto; enum connection_state state; long probe_timeout; struct queue q[2]; struct sockaddr client_addr; unsigned int addrlen; int local_endpoint; long last_active; struct connection *timeout_prev; int target_sock; }

user_defined_types: struct sslhcfg_protocols_item { char *name; char *host; char *port; int service_is_present; char *service; int is_udp; int udp_timeout; int fork; int tfo_ok; int transparent; int resolve_on_forward; int log_level; int keepalive; unsigned long sni_hostnames_len; char **sni_hostnames; unsigned long alpn_protocols_len; char **alpn_protocols; unsigned long regex_patterns_len; char **regex_patterns; int minlength_is_present; int minlength; int (*probe)(char *, long, struct sslhcfg_protocols_item *); struct addrinfo *saddr; void *data; struct dl_list timeouts; }


decompiled_code:
__int64 __fastcall active_queue(__int64 a1, unsigned int a2)
{
if ( *(_DWORD *)(a1 + 32) == a2 )
return 0LL;
if ( *(_DWORD *)(a1 + 64) != a2 )
{
print_message(
msg_int_error,
*((_QWORD *)&msg_int_error + 1),
"file descriptor %d not found in connection object\n",
a2);
exit(1);
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned int a2)
{
if ( *(_DWORD *)(a1 + 32) == a2 )
return 0LL;
if ( *(_DWORD *)(a1 + 64) != a2 )
{
print_message(
msg_int_error,
*((_QWORD *)&msg_int_error + 1),
"file descriptor %d not found in connection object\n",
a2);
exit(1);
}
return 1LL;
}

original_code:
static int active_queue(struct connection* cnx, int fd)
{
    if (cnx->q[0].fd == fd) return 0;
    if (cnx->q[1].fd == fd) return 1;
    print_message(msg_int_error, "file descriptor %d not found in connection object\n", fd);
    exit(1);
}

canonical_original_code:
static int active_queue(struct connection *cnx, int fd)
{
    if (cnx->q[0].fd == fd) return 0;
    if (cnx->q[1].fd == fd) return 1;
    print_message(msg_int_error, "file descriptor %d not found in connection object\n", fd);
    exit(1);
}

variable_types: fd int

user_defined_types: enum connection_state { ST_PROBING=1, ST_SHOVELING=2 }

user_defined_types: struct queue { int fd; void *begin_deferred_data; void *deferred_data; int deferred_data_size; }

user_defined_types: struct dl_list { struct connection *head; struct connection *tail; }


shovel

decompiled_code:
__int64 __fastcall shovel(__int64 a1, int a2, __int64 a3)
{
__int64 v4; // rbx
__int64 result; // rax

v4 = a1 + 32LL * a2;
print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "activity on fd%d\n", *(unsigned int *)(v4 + 32));
result = fd2fd(a1 + 32 * (1 - a2 + 1LL), a1 + 32 * (a2 + 1LL));
if ( (_DWORD)result == -2 )
{
watchers_add_write(*(_QWORD *)(a3 + 24), *(unsigned int *)(32LL * (1 - a2) + a1 + 32));
result = watchers_del_read(*(_QWORD *)(a3 + 24), *(unsigned int *)(v4 + 32));
}
else if ( (int)result >= -2 )
{
result = (unsigned int)(result + 1);
if ( (unsigned int)result <= 1 )
result = tidy_connection(a1, a3);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, int a2, __int64 a3)
{
__int64 v4; // rbx
__int64 result; // rax

v4 = a1 + 32LL * a2;
print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "activity on fd%d\n", *(unsigned int *)(v4 + 32));
result = fd2fd(a1 + 32 * (1 - a2 + 1LL), a1 + 32 * (a2 + 1LL));
if ( (_DWORD)result == -2 )
{
watchers_add_write(*(_QWORD *)(a3 + 24), *(unsigned int *)(32LL * (1 - a2) + a1 + 32));
result = watchers_del_read(*(_QWORD *)(a3 + 24), *(unsigned int *)(v4 + 32));
}
else if ( (int)result >= -2 )
{
result = (unsigned int)(result + 1);
if ( (unsigned int)result <= 1 )
result = tidy_connection(a1, a3);
}
return result;
}

original_code:
int shovel(struct connection *cnx)
{
   fd_set fds;
   int res, i;
   int max_fd = (((cnx->q[0].fd) > (cnx->q[1].fd)) ? (cnx->q[0].fd) : (cnx->q[1].fd)) + 1;
   do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&fds)->fds_bits)[0]) : "memory"); } while (0);
   while (1) {
      ((void) (((&fds)->fds_bits)[((cnx->q[0].fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((cnx->q[0].fd) % (8 * (int) sizeof (__fd_mask)))))));
      ((void) (((&fds)->fds_bits)[((cnx->q[1].fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((cnx->q[1].fd) % (8 * (int) sizeof (__fd_mask)))))));
      res = select(
                   max_fd,
                   &fds,
                   ((void *)0),
                   ((void *)0),
                   ((void *)0)
                  );
      if (res == -1) { print_message(msg_system_error, "%s:%d:", "sslh-fork.c", 56); perror("select"); exit(1); };
      for (i = 0; i < 2; i++) {
          if (((((&fds)->fds_bits)[((cnx->q[i].fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((cnx->q[i].fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
              res = fd2fd(&cnx->q[1-i], &cnx->q[i]);
              if (res == 0) {
                  print_message(msg_fd, "%s %s", i ? "client" : "server", "socket closed\n");
                  return res;
              }
          }
      }
   }
}

canonical_original_code:
int shovel(struct connection *cnx)
{
   struct fd_set fds;
   int res; int i;
   int max_fd = (((cnx->q[0].fd) > (cnx->q[1].fd)) ? (cnx->q[0].fd) : (cnx->q[1].fd)) + 1;
   do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&fds)->fds_bits)[0]) : "memory"); } while (0);
   while (1) {
      ((void) (((&fds)->fds_bits)[((cnx->q[0].fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((cnx->q[0].fd) % (8 * (int) sizeof (__fd_mask)))))));
      ((void) (((&fds)->fds_bits)[((cnx->q[1].fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((cnx->q[1].fd) % (8 * (int) sizeof (__fd_mask)))))));
      res = select(
                   max_fd,
                   &fds,
                   ((void *)0),
                   ((void *)0),
                   ((void *)0)
                  );
      if (res == -1) { print_message(msg_system_error, "%s:%d:", "sslh-fork.c", 56); perror("select"); exit(1); };
      for (i = 0; i < 2; i++) {
          if (((((&fds)->fds_bits)[((cnx->q[i].fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((cnx->q[i].fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
              res = fd2fd(&cnx->q[1-i], &cnx->q[i]);
              if (res == 0) {
                  print_message(msg_fd, "%s %s", i ? "client" : "server", "socket closed\n");
                  return res;
              }
          }
      }
   }
}

variable_types:
fds
struct fd_set { long fds_bits[-1]; }

variable_types: i int


decompiled_code:
__int64 __fastcall shovel_single(int *a1)
{
int v1; // er15
int v2; // er15
int v3; // esi
int v4; // esi
int *v5; // rax
int *v6; // rdx
int v7; // esi
int v8; // esi
int v9; // er12
int v10; // eax
int v11; // eax
int *v12; // rbx
int v13; // eax
const char *v14; // rcx
fd_set writefds; // [rsp+10h] [rbp-138h] BYREF
fd_set readfds; // [rsp+90h] [rbp-B8h] BYREF

v1 = a1[8];
if ( a1[16] >= v1 )
v1 = a1[16];
v2 = v1 + 1;
memset(&readfds, 0, sizeof(readfds));
memset(&writefds, 0, sizeof(writefds));
LABEL_25:
v12 = a1 + 8;
v6 = a1 + 16;
v5 = a1 + 8;
do
{
if ( v5[6] )
{
v7 = *v5 + 63;
if ( *v5 >= 0 )
v7 = *v5;
writefds.fds_bits[v7 >> 6] |= 1LL << (*v5 % 64);
v8 = *v6 + 63;
if ( *v6 >= 0 )
v8 = *v6;
readfds.fds_bits[v8 >> 6] &= ~(1LL << (*v6 % 64));
}
else
{
v3 = *v5 + 63;
if ( *v5 >= 0 )
v3 = *v5;
writefds.fds_bits[v3 >> 6] &= ~(1LL << (*v5 % 64));
v4 = *v6 + 63;
if ( *v6 >= 0 )
v4 = *v6;
readfds.fds_bits[v4 >> 6] |= 1LL << (*v6 % 64);
}
v5 += 8;
v6 -= 8;
}
while ( a1 != v6 );
if ( select(v2, &readfds, &writefds, 0LL, 0LL) == -1 )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "tcp-listener.c", 202LL);
perror("select");
exit(1);
}
v9 = 0;
while ( 1 )
{
v10 = *v12 + 63;
if ( *v12 >= 0 )
v10 = *v12;
if ( (writefds.fds_bits[v10 >> 6] & (1LL << (*v12 % 64))) != 0 && (unsigned int)flush_deferred(v12) == -1 )
{
v13 = *_errno_location();
if ( v13 == 32 || v13 == 104 )
break;
}
v11 = *v12 + 63;
if ( *v12 >= 0 )
v11 = *v12;
if ( (readfds.fds_bits[v11 >> 6] & (1LL << (*v12 % 64))) != 0
&& !(unsigned int)fd2fd(2LL * (_QWORD)a1 + 96 - (_QWORD)v12, v12) )
{
return print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "socket closed\n");
}
++v9;
v12 += 8;
if ( v9 == 2 )
goto LABEL_25;
}
v14 = "server";
if ( !v9 )
v14 = "client";
return print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "%s socket closed\n", v14);
}

canonical_decompiled_code:
__int64 __fastcall func5(int *a1)
{
int v1; // er15
int v2; // er15
int v3; // esi
int v4; // esi
int *v5; // rax
int *v6; // rdx
int v7; // esi
int v8; // esi
int v9; // er12
int v10; // eax
int v11; // eax
int *v12; // rbx
int v13; // eax
const char *v14; // rcx
fd_set writefds; // [rsp+10h] [rbp-138h] BYREF
fd_set readfds; // [rsp+90h] [rbp-B8h] BYREF

v1 = a1[8];
if ( a1[16] >= v1 )
v1 = a1[16];
v2 = v1 + 1;
memset(&readfds, 0, sizeof(readfds));
memset(&writefds, 0, sizeof(writefds));
LABEL_25:
v12 = a1 + 8;
v6 = a1 + 16;
v5 = a1 + 8;
do
{
if ( v5[6] )
{
v7 = *v5 + 63;
if ( *v5 >= 0 )
v7 = *v5;
writefds.fds_bits[v7 >> 6] |= 1LL << (*v5 % 64);
v8 = *v6 + 63;
if ( *v6 >= 0 )
v8 = *v6;
readfds.fds_bits[v8 >> 6] &= ~(1LL << (*v6 % 64));
}
else
{
v3 = *v5 + 63;
if ( *v5 >= 0 )
v3 = *v5;
writefds.fds_bits[v3 >> 6] &= ~(1LL << (*v5 % 64));
v4 = *v6 + 63;
if ( *v6 >= 0 )
v4 = *v6;
readfds.fds_bits[v4 >> 6] |= 1LL << (*v6 % 64);
}
v5 += 8;
v6 -= 8;
}
while ( a1 != v6 );
if ( select(v2, &readfds, &writefds, 0LL, 0LL) == -1 )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "tcp-listener.c", 202LL);
perror("select");
exit(1);
}
v9 = 0;
while ( 1 )
{
v10 = *v12 + 63;
if ( *v12 >= 0 )
v10 = *v12;
if ( (writefds.fds_bits[v10 >> 6] & (1LL << (*v12 % 64))) != 0 && (unsigned int)flush_deferred(v12) == -1 )
{
v13 = *_errno_location();
if ( v13 == 32 || v13 == 104 )
break;
}
v11 = *v12 + 63;
if ( *v12 >= 0 )
v11 = *v12;
if ( (readfds.fds_bits[v11 >> 6] & (1LL << (*v12 % 64))) != 0
&& !(unsigned int)fd2fd(2LL * (_QWORD)a1 + 96 - (_QWORD)v12, v12) )
{
return print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "socket closed\n");
}
++v9;
v12 += 8;
if ( v9 == 2 )
goto LABEL_25;
}
v14 = "server";
if ( !v9 )
v14 = "client";
return print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "%s socket closed\n", v14);
}

canonical_original_code:
static void shovel_single(struct connection *cnx)
{
   struct fd_set fds_r; struct fd_set fds_w;
   int res; int i;
   int max_fd = (((cnx->q[0].fd) > (cnx->q[1].fd)) ? (cnx->q[0].fd) : (cnx->q[1].fd)) + 1;
   do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&fds_r)->__fds_bits)[0]) : "memory"); } while (0);
   do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&fds_w)->__fds_bits)[0]) : "memory"); } while (0);
   while (1) {
      for (i = 0; i < 2; i++) {
         if (cnx->q[i].deferred_data_size) {
            ((void) (((&fds_w)->__fds_bits)[((cnx->q[i].fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((cnx->q[i].fd) % (8 * (int) sizeof (__fd_mask)))))));
            ((void) (((&fds_r)->__fds_bits)[((cnx->q[1-i].fd) / (8 * (int) sizeof (__fd_mask)))] &= ~((__fd_mask) (1UL << ((cnx->q[1-i].fd) % (8 * (int) sizeof (__fd_mask)))))));
         } else {
            ((void) (((&fds_w)->__fds_bits)[((cnx->q[i].fd) / (8 * (int) sizeof (__fd_mask)))] &= ~((__fd_mask) (1UL << ((cnx->q[i].fd) % (8 * (int) sizeof (__fd_mask)))))));
            ((void) (((&fds_r)->__fds_bits)[((cnx->q[1-i].fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((cnx->q[1-i].fd) % (8 * (int) sizeof (__fd_mask)))))));
         }
      }
      res = select(
                   max_fd,
                   &fds_r,
                   &fds_w,
                   ((void *)0),
                   ((void *)0)
                  );
      if (res == -1) { print_message(msg_system_error, "%s:%d:", "tcp-listener.c", 202); perror("select"); exit(1); };
      for (i = 0; i < 2; i++) {
          if (((((&fds_w)->__fds_bits)[((cnx->q[i].fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((cnx->q[i].fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
              res = flush_deferred(&cnx->q[i]);
              if ((res == -1) && (((*__errno_location ()) == 32) || ((*__errno_location ()) == 104))) {
                  print_message(msg_fd, "%s socket closed\n", i ? "server" : "client");
                  return;
              }
          }
          if (((((&fds_r)->__fds_bits)[((cnx->q[i].fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((cnx->q[i].fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
              res = fd2fd(&cnx->q[1-i], &cnx->q[i]);
              if (!res) {
                  print_message(msg_fd, "socket closed\n");
                  return;
              }
          }
      }
   }
}


decompiled_code:
void __fastcall __noreturn connect_proxy(int *a1)
{
int v1; // eax
unsigned int v2; // ebp
int v3; // eax
int v4; // er12

v1 = dup(a1[8]);
if ( v1 == -1 )
{
v2 = a1[8];
}
else
{
v2 = v1;
close(a1[8]);
a1[8] = v2;
}
v3 = connect_addr(a1, v2, 1LL);
v4 = v3;
if ( v3 != -1 )
{
a1[16] = v3;
log_connection(0LL, a1);
shovel_single(a1);
close(v2);
close(v4);
print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "connection closed down\n");
exit(0);
}
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "tcp-listener.c", 243LL);
perror("connect");
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func6(int *a1)
{
int v1; // eax
unsigned int v2; // ebp
int v3; // eax
int v4; // er12

v1 = dup(a1[8]);
if ( v1 == -1 )
{
v2 = a1[8];
}
else
{
v2 = v1;
close(a1[8]);
a1[8] = v2;
}
v3 = connect_addr(a1, v2, 1LL);
v4 = v3;
if ( v3 != -1 )
{
a1[16] = v3;
log_connection(0LL, a1);
func5(a1);
close(v2);
close(v4);
print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "connection closed down\n");
exit(0);
}
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "tcp-listener.c", 243LL);
perror("connect");
exit(1);
}

original_code:
static void connect_proxy(struct connection *cnx)
{
    int in_socket;
    int out_socket;
    in_socket = dup(cnx->q[0].fd);
    if (in_socket == -1) {
        in_socket = cnx->q[0].fd;
    } else {
        close(cnx->q[0].fd);
        cnx->q[0].fd = in_socket;
    }
    out_socket = connect_addr(cnx, in_socket, BLOCKING);
    if (out_socket == -1) { print_message(msg_system_error, "%s:%d:", "tcp-listener.c", 243); perror("connect"); exit(1); };
    cnx->q[1].fd = out_socket;
    log_connection(((void *)0), cnx);
    shovel_single(cnx);
    close(in_socket);
    close(out_socket);
    print_message(msg_fd, "connection closed down\n");
    exit(0);
}


decompiled_code:
__int64 __fastcall has_match(__int64 a1, __int64 a2, const void *a3, size_t a4)
{
char *v6; // rax
char *v7; // r12
__int64 v8; // rbx
__int64 result; // rax

v6 = (char *)malloc(a4 + 1);
if ( !v6 )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "tls.c", 274LL);
perror("malloc");
exit(1);
}
v7 = v6;
memcpy(v6, a3, a4);
v7[a4] = 0;
if ( a2 )
{
v8 = 0LL;
while ( 1 )
{
print_message(
msg_probe_error,
*((_QWORD *)&msg_probe_error + 1),
"matching [%.*s] with [%s]\n",
(unsigned int)a4,
a3,
*(_QWORD *)(a1 + 8 * v8));
if ( !fnmatch(*(const char **)(a1 + 8 * v8), v7, 0) )
break;
if ( ++v8 == a2 )
goto LABEL_6;
}
free(v7);
result = 1LL;
}
else
{
LABEL_6:
free(v7);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, const void *a3, size_t a4)
{
char *v6; // rax
char *v7; // r12
__int64 v8; // rbx
__int64 result; // rax

v6 = (char *)malloc(a4 + 1);
if ( !v6 )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "tls.c", 274LL);
perror("malloc");
exit(1);
}
v7 = v6;
memcpy(v6, a3, a4);
v7[a4] = 0;
if ( a2 )
{
v8 = 0LL;
while ( 1 )
{
print_message(
msg_probe_error,
*((_QWORD *)&msg_probe_error + 1),
"matching [%.*s] with [%s]\n",
(unsigned int)a4,
a3,
*(_QWORD *)(a1 + 8 * v8));
if ( !fnmatch(*(const char **)(a1 + 8 * v8), v7, 0) )
break;
if ( ++v8 == a2 )
goto LABEL_6;
}
free(v7);
result = 1LL;
}
else
{
LABEL_6:
free(v7);
result = 0LL;
}
return result;
}

original_code:
static int
has_match(const char** list, size_t list_len, const char* name, size_t name_len) {
    const char **item;
    int i;
    char *name_nullterminated = malloc(name_len+1);
    if (!name_nullterminated) { print_message(msg_system_error, "%s:%d:", "tls.c", 274); perror("malloc"); exit(1); };
    memcpy(name_nullterminated, name, name_len);
    name_nullterminated[name_len]='\0';
    for (i = 0; i < list_len; i++) {
        item = &list[i];
        print_message(msg_probe_error, "matching [%.*s] with [%s]\n", (int)name_len, name, *item);
        if(!fnmatch(*item, name_nullterminated, 0)) {
            free(name_nullterminated);
            return 1;
        }
    }
    free(name_nullterminated);
    return 0;
}

canonical_original_code:
static int has_match(char **list, unsigned long list_len, char *name, unsigned long name_len) {
    char **item;
    int i;
    char *name_nullterminated = malloc(name_len+1);
    if (!name_nullterminated) { print_message(msg_system_error, "%s:%d:", "tls.c", 274); perror("malloc"); exit(1); };
    memcpy(name_nullterminated, name, name_len);
    name_nullterminated[name_len]='\0';
    for (i = 0; i < list_len; i++) {
        item = &list[i];
        print_message(msg_probe_error, "matching [%.*s] with [%s]\n", (int)name_len, name, *item);
        if(!fnmatch(*item, name_nullterminated, 0)) {
            free(name_nullterminated);
            return 1;
        }
    }
    free(name_nullterminated);
    return 0;
}

variable_types:
list
char **

variable_types:
name
char *

variable_types:
item
char **


decompiled_code:
__int64 __fastcall parse_server_name_extension(__int64 a1, __int64 a2, unsigned __int64 a3)
{
int v5; // ebx
size_t v6; // rsi
unsigned __int64 v7; // rbp
__int64 v8; // rcx
__int64 v9; // rdx
char v10; // al

if ( a3 <= 5 )
{
v7 = 2LL;
LABEL_12:
v5 = (a3 == v7) - 5;
}
else
{
v5 = *(unsigned __int8 *)(a2 + 4) + (*(unsigned __int8 *)(a2 + 3) << 8);
v6 = v5;
v7 = v5 + 5;
if ( a3 < v7 )
{
v5 = -5;
}
else
{
v8 = 2LL;
v9 = 5LL;
while ( 1 )
{
v10 = *(_BYTE *)(a2 + v8);
if ( !v10 )
break;
print_message(
msg_probe_error,
*((_QWORD *)&msg_probe_error + 1),
"Unknown server name extension name type: %d\n",
(unsigned int)v10);
v9 = v7 + 3;
if ( v7 + 3 >= a3 )
goto LABEL_12;
v5 = *(unsigned __int8 *)(a2 + v7 + 2) + (*(unsigned __int8 *)(a2 + v7 + 1) << 8);
v6 = v5;
v8 = v7;
if ( v7 + v5 + 3 > a3 )
return (unsigned int)-5;
v7 += v5 + 3;
}
if ( !(unsigned int)has_match(*(_QWORD *)(a1 + 8), *(int *)(a1 + 4), (const void *)(a2 + v9), v6) )
v5 = -4;
}
}
return (unsigned int)v5;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2, unsigned __int64 a3)
{
int v5; // ebx
size_t v6; // rsi
unsigned __int64 v7; // rbp
__int64 v8; // rcx
__int64 v9; // rdx
char v10; // al

if ( a3 <= 5 )
{
v7 = 2LL;
LABEL_12:
v5 = (a3 == v7) - 5;
}
else
{
v5 = *(unsigned __int8 *)(a2 + 4) + (*(unsigned __int8 *)(a2 + 3) << 8);
v6 = v5;
v7 = v5 + 5;
if ( a3 < v7 )
{
v5 = -5;
}
else
{
v8 = 2LL;
v9 = 5LL;
while ( 1 )
{
v10 = *(_BYTE *)(a2 + v8);
if ( !v10 )
break;
print_message(
msg_probe_error,
*((_QWORD *)&msg_probe_error + 1),
"Unknown server name extension name type: %d\n",
(unsigned int)v10);
v9 = v7 + 3;
if ( v7 + 3 >= a3 )
goto LABEL_12;
v5 = *(unsigned __int8 *)(a2 + v7 + 2) + (*(unsigned __int8 *)(a2 + v7 + 1) << 8);
v6 = v5;
v8 = v7;
if ( v7 + v5 + 3 > a3 )
return (unsigned int)-5;
v7 += v5 + 3;
}
if ( !(unsigned int)func0(*(_QWORD *)(a1 + 8), *(int *)(a1 + 4), (const void *)(a2 + v9), v6) )
v5 = -4;
}
}
return (unsigned int)v5;
}

original_code:
static int
parse_server_name_extension(const struct TLSProtocol *tls_data, const char *data, size_t data_len) {
    size_t pos = 2;
    size_t len;
    while (pos + 3 < data_len) {
        len = ((unsigned char)data[pos + 1] << 8) +
              (unsigned char)data[pos + 2];
        if (pos + 3 + len > data_len)
            return -5;
        switch (data[pos]) {
            case 0x00:
                if(has_match(tls_data->sni_hostname_list, tls_data->sni_list_len, data + pos + 3, len)) {
                    return len;
                } else {
                    return -4;
                }
            default:
                print_message(msg_probe_error, "Unknown server name extension name type: %d\n",
                      data[pos]);
        }
        pos += 3 + len;
    }
    if (pos != data_len)
        return -5;
    return -4;
}

canonical_original_code:
static int parse_server_name_extension(struct TLSProtocol *tls_data, char *data, unsigned long data_len) {
    unsigned long pos = 2;
    unsigned long len;
    while (pos + 3 < data_len) {
        len = ((unsigned char)data[pos + 1] << 8) +
              (unsigned char)data[pos + 2];
        if (pos + 3 + len > data_len)
            return -5;
        switch (data[pos]) {
            case 0x00:
                if(has_match(tls_data->sni_hostname_list, tls_data->sni_list_len, data + pos + 3, len)) {
                    return len;
                } else {
                    return -4;
                }
            default:
                print_message(msg_probe_error, "Unknown server name extension name type: %d\n",
                      data[pos]);
        }
        pos += 3 + len;
    }
    if (pos != data_len)
        return -5;
    return -4;
}

variable_types: struct TLSProtocol { struct TLS_MATCHMODE { int tls_match_sni; int tls_match_alpn; } match_mode; int sni_list_len; char **sni_hostname_list; int alpn_list_len; char **alpn_protocol_list; } *

variable_types:
data
char *

variable_types:
pos
unsigned long

variable_types:
len
unsigned long

user_defined_types: struct TLSProtocol { struct TLS_MATCHMODE match_mode; int sni_list_len; char **sni_hostname_list; int alpn_list_len; char **alpn_protocol_list; }


decompiled_code:
__int64 __fastcall parse_alpn_extension(__int64 a1, __int64 a2, unsigned __int64 a3)
{
unsigned __int8 v4; // r12
size_t v5; // rcx
unsigned __int64 v6; // rbx
__int64 v7; // rbp
const void *v9; // rbp

if ( a3 > 3 )
{
v4 = *(_BYTE *)(a2 + 2);
v5 = v4;
v6 = v4 + 3LL;
if ( a3 < v6 )
return 4294967291LL;
v7 = 3LL;
while ( 1 )
{
if ( v5 )
{
v9 = (const void *)(a2 + v7);
if ( (unsigned int)has_match(*(_QWORD *)(a1 + 24), *(int *)(a1 + 16), v9, v5) )
return v4;
print_message(msg_probe_error, *((_QWORD *)&msg_probe_error + 1), "Unknown ALPN name: %.*s\n", v4, v9);
}
v7 = v6 + 1;
if ( v6 + 1 >= a3 )
return (unsigned int)(a3 == v6) - 5;
v4 = *(_BYTE *)(a2 + v6);
v5 = v4;
v6 += v4 + 1LL;
if ( v6 > a3 )
return 4294967291LL;
}
}
v6 = 2LL;
return (unsigned int)(a3 == v6) - 5;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2, unsigned __int64 a3)
{
unsigned __int8 v4; // r12
size_t v5; // rcx
unsigned __int64 v6; // rbx
__int64 v7; // rbp
const void *v9; // rbp

if ( a3 > 3 )
{
v4 = *(_BYTE *)(a2 + 2);
v5 = v4;
v6 = v4 + 3LL;
if ( a3 < v6 )
return 4294967291LL;
v7 = 3LL;
while ( 1 )
{
if ( v5 )
{
v9 = (const void *)(a2 + v7);
if ( (unsigned int)func0(*(_QWORD *)(a1 + 24), *(int *)(a1 + 16), v9, v5) )
return v4;
print_message(msg_probe_error, *((_QWORD *)&msg_probe_error + 1), "Unknown ALPN name: %.*s\n", v4, v9);
}
v7 = v6 + 1;
if ( v6 + 1 >= a3 )
return (unsigned int)(a3 == v6) - 5;
v4 = *(_BYTE *)(a2 + v6);
v5 = v4;
v6 += v4 + 1LL;
if ( v6 > a3 )
return 4294967291LL;
}
}
v6 = 2LL;
return (unsigned int)(a3 == v6) - 5;
}

original_code:
static int
parse_alpn_extension(const struct TLSProtocol *tls_data, const char *data, size_t data_len) {
    size_t pos = 2;
    size_t len;
    while (pos + 1 < data_len) {
        len = (unsigned char)data[pos];
        if (pos + 1 + len > data_len)
            return -5;
        if (len > 0 && has_match(tls_data->alpn_protocol_list, tls_data->alpn_list_len, data + pos + 1, len)) {
            return len;
        } else if (len > 0) {
            print_message(msg_probe_error, "Unknown ALPN name: %.*s\n", (int)len, data + pos + 1);
        }
        pos += 1 + len;
    }
    if (pos != data_len)
        return -5;
    return -4;
}

canonical_original_code:
static int parse_alpn_extension(struct TLSProtocol *tls_data, char *data, unsigned long data_len) {
    unsigned long pos = 2;
    unsigned long len;
    while (pos + 1 < data_len) {
        len = (unsigned char)data[pos];
        if (pos + 1 + len > data_len)
            return -5;
        if (len > 0 && has_match(tls_data->alpn_protocol_list, tls_data->alpn_list_len, data + pos + 1, len)) {
            return len;
        } else if (len > 0) {
            print_message(msg_probe_error, "Unknown ALPN name: %.*s\n", (int)len, data + pos + 1);
        }
        pos += 1 + len;
    }
    if (pos != data_len)
        return -5;
    return -4;
}

user_defined_types: struct TLS_MATCHMODE { int tls_match_sni; int tls_match_alpn; }


decompiled_code:
__int64 __fastcall parse_extensions(unsigned __int8 *a1, __int64 a2, unsigned __int64 a3)
{
int v5; // ebx
unsigned __int64 v6; // rdx
unsigned __int64 v7; // rbx
int v8; // er15
int v9; // er14
unsigned __int64 v10; // rcx
__int64 v11; // rsi
int v12; // eax
unsigned __int64 v13; // rax
int v14; // eax
bool v15; // dl
unsigned __int8 v16; // al

if ( !a1 )
return (unsigned int)-1;
if ( a3 <= 3 )
{
if ( a3 )
return (unsigned int)-5;
v16 = *a1;
v15 = 0;
return v15 & ((v16 >> 1) ^ 1);
}
v5 = *(unsigned __int8 *)(a2 + 3) + (*(unsigned __int8 *)(a2 + 2) << 8);
v6 = v5;
v7 = v5 + 4;
if ( a3 < v7 )
return (unsigned int)-5;
v8 = 0;
v9 = 0;
v10 = 0LL;
v11 = 4LL;
while ( 1 )
{
if ( *(unsigned __int8 *)(a2 + v10 + 1) + (*(unsigned __int8 *)(a2 + v10) << 8) )
{
if ( *(unsigned __int8 *)(a2 + v10 + 1) + (*(unsigned __int8 *)(a2 + v10) << 8) == 16LL && (*a1 & 2) != 0 )
{
v14 = parse_alpn_extension((__int64)a1, a2 + v11, v6);
v8 = v14;
if ( v14 < 0 )
return (unsigned int)v14;
}
}
else if ( (*a1 & 1) != 0 )
{
v9 = parse_server_name_extension((__int64)a1, a2 + v11, v6);
if ( v9 < 0 )
return (unsigned int)v9;
}
v11 = v7 + 4;
if ( v7 + 4 > a3 )
break;
v12 = *(unsigned __int8 *)(a2 + v7 + 3) + (*(unsigned __int8 *)(a2 + v7 + 2) << 8);
v6 = v12;
v13 = v7 + v12 + 4;
v10 = v7;
if ( v13 > a3 )
return (unsigned int)-5;
v7 = v13;
}
if ( a3 != v7 )
return (unsigned int)-5;
v15 = v9 != 0;
if ( !v9 || (v9 = 1, !v8) )
{
v16 = *a1;
if ( (*a1 & 1) != 0 )
return v15 & ((v16 >> 1) ^ 1);
v9 = 1;
if ( !v8 )
return v15 & ((v16 >> 1) ^ 1);
}
return (unsigned int)v9;
}

original_code:
static int
parse_extensions(const struct TLSProtocol *tls_data, const char *data, size_t data_len) {
    size_t pos = 0;
    size_t len;
    int sni_match = 0, alpn_match = 0;
    if (tls_data == ((void *)0))
        return -1;
    while (pos + 4 <= data_len) {
        len = ((unsigned char) data[pos + 2] << 8) +
              (unsigned char) data[pos + 3];
        if (pos + 4 + len > data_len)
            return -5;
        size_t extension_type = ((unsigned char) data[pos] << 8) +
                                (unsigned char) data[pos + 1];
        if (extension_type == 0x00 && tls_data->match_mode.tls_match_sni) {
            sni_match = parse_server_name_extension(tls_data, data + pos + 4, len);
            if (sni_match < 0) return sni_match;
        } else if (extension_type == 0x10 && tls_data->match_mode.tls_match_alpn) {
            alpn_match = parse_alpn_extension(tls_data, data + pos + 4, len);
            if (alpn_match < 0) return alpn_match;
        }
        pos += 4 + len;
    }
    if (pos != data_len)
        return -5;
    return (sni_match && alpn_match)
        || (!tls_data->match_mode.tls_match_sni && alpn_match)
        || (!tls_data->match_mode.tls_match_alpn && sni_match);
}

canonical_original_code:
static int parse_extensions(struct TLSProtocol *tls_data, char *data, unsigned long data_len) {
    unsigned long pos = 0;
    unsigned long len;
    int sni_match = 0; int alpn_match = 0;
    if (tls_data == ((void *)0))
        return -1;
    while (pos + 4 <= data_len) {
        len = ((unsigned char) data[pos + 2] << 8) +
              (unsigned char) data[pos + 3];
        if (pos + 4 + len > data_len)
            return -5;
        unsigned long extension_type = ((unsigned char) data[pos] << 8) +
                                (unsigned char) data[pos + 1];
        if (extension_type == 0x00 && tls_data->match_mode.tls_match_sni) {
            sni_match = parse_server_name_extension(tls_data, data + pos + 4, len);
            if (sni_match < 0) return sni_match;
        } else if (extension_type == 0x10 && tls_data->match_mode.tls_match_alpn) {
            alpn_match = parse_alpn_extension(tls_data, data + pos + 4, len);
            if (alpn_match < 0) return alpn_match;
        }
        pos += 4 + len;
    }
    if (pos != data_len)
        return -5;
    return (sni_match && alpn_match)
        || (!tls_data->match_mode.tls_match_sni && alpn_match)
        || (!tls_data->match_mode.tls_match_alpn && sni_match);
}


decompiled_code:
__int64 __fastcall parse_tls_header(unsigned __int8 *a1, _BYTE *a2, unsigned __int64 a3)
{
char v3; // r9
__int64 v4; // r8
__int64 v5; // rcx
unsigned __int64 v6; // rax
__int64 v7; // rcx
__int64 v8; // rax
__int64 v9; // rcx
__int64 v10; // r8
unsigned __int64 v11; // rax
unsigned int v12; // edx

if ( a3 <= 4 )
return 4294967294LL;
if ( *a2 == 22 )
{
v3 = a2[1];
v4 = (unsigned __int8)a2[2];
if ( v3 <= 2 )
{
print_message(
msg_probe_error,
*((_QWORD *)&msg_probe_error + 1),
"Received SSL %d.%d handshake which cannot be parsed.\n",
(unsigned int)v3,
(unsigned int)(char)v4);
v12 = -3;
}
else
{
v5 = (unsigned __int8)a2[4];
v6 = ((unsigned __int8)a2[3] << 8) + (int)v5 + 5;
if ( a3 > v6 )
a3 = ((unsigned __int8)a2[3] << 8) + (int)v5 + 5;
if ( v6 > a3 )
{
v12 = -2;
}
else if ( a3 <= 5 )
{
v12 = -5;
}
else if ( a2[5] == 1 )
{
if ( a3 <= 0x2B )
{
v12 = -5;
}
else
{
v7 = (unsigned __int8)a2[43];
if ( v7 + 46 > a3 )
{
v12 = -5;
}
else
{
v8 = v7 + 44 + (unsigned __int8)a2[v7 + 45] + ((unsigned __int8)a2[v7 + 44] << 8);
if ( v8 + 3 > a3 )
{
v12 = -5;
}
else
{
v9 = v8 + 2 + (unsigned __int8)a2[v8 + 2];
if ( (_BYTE)v4 == 0 && v3 == 3 && a3 == v9 + 1 )
{
print_message(
msg_probe_error,
*((_QWORD *)&msg_probe_error + 1),
"Received SSL 3.0 handshake without extensions\n");
v12 = -3;
}
else
{
v10 = v9 + 3;
if ( v9 + 3 > a3 )
{
v12 = -5;
}
else
{
v11 = (unsigned __int8)a2[v9 + 2] + ((unsigned __int8)a2[v9 + 1] << 8);
if ( v10 + v11 > a3 )
{
v12 = -5;
}
else if ( a1 )
{
v12 = 1;
if ( (*a1 & 3) != 0 )
v12 = parse_extensions(a1, (__int64)&a2[v10], v11);
}
else
{
v12 = 1;
}
}
}
}
}
}
}
else
{
print_message(msg_probe_error, *((_QWORD *)&msg_probe_error + 1), "Not a client hello\n", v5, v4);
v12 = -5;
}
}
}
else
{
print_message(msg_probe_info, *((_QWORD *)&msg_probe_info + 1), "Request did not begin with TLS handshake.\n");
v12 = -5;
}
return v12;
}

canonical_decompiled_code:
__int64 __fastcall func4(unsigned __int8 *a1, _BYTE *a2, unsigned __int64 a3)
{
char v3; // r9
__int64 v4; // r8
__int64 v5; // rcx
unsigned __int64 v6; // rax
__int64 v7; // rcx
__int64 v8; // rax
__int64 v9; // rcx
__int64 v10; // r8
unsigned __int64 v11; // rax
unsigned int v12; // edx

if ( a3 <= 4 )
return 4294967294LL;
if ( *a2 == 22 )
{
v3 = a2[1];
v4 = (unsigned __int8)a2[2];
if ( v3 <= 2 )
{
print_message(
msg_probe_error,
*((_QWORD *)&msg_probe_error + 1),
"Received SSL %d.%d handshake which cannot be parsed.\n",
(unsigned int)v3,
(unsigned int)(char)v4);
v12 = -3;
}
else
{
v5 = (unsigned __int8)a2[4];
v6 = ((unsigned __int8)a2[3] << 8) + (int)v5 + 5;
if ( a3 > v6 )
a3 = ((unsigned __int8)a2[3] << 8) + (int)v5 + 5;
if ( v6 > a3 )
{
v12 = -2;
}
else if ( a3 <= 5 )
{
v12 = -5;
}
else if ( a2[5] == 1 )
{
if ( a3 <= 0x2B )
{
v12 = -5;
}
else
{
v7 = (unsigned __int8)a2[43];
if ( v7 + 46 > a3 )
{
v12 = -5;
}
else
{
v8 = v7 + 44 + (unsigned __int8)a2[v7 + 45] + ((unsigned __int8)a2[v7 + 44] << 8);
if ( v8 + 3 > a3 )
{
v12 = -5;
}
else
{
v9 = v8 + 2 + (unsigned __int8)a2[v8 + 2];
if ( (_BYTE)v4 == 0 && v3 == 3 && a3 == v9 + 1 )
{
print_message(
msg_probe_error,
*((_QWORD *)&msg_probe_error + 1),
"Received SSL 3.0 handshake without extensions\n");
v12 = -3;
}
else
{
v10 = v9 + 3;
if ( v9 + 3 > a3 )
{
v12 = -5;
}
else
{
v11 = (unsigned __int8)a2[v9 + 2] + ((unsigned __int8)a2[v9 + 1] << 8);
if ( v10 + v11 > a3 )
{
v12 = -5;
}
else if ( a1 )
{
v12 = 1;
if ( (*a1 & 3) != 0 )
v12 = func3(a1, (__int64)&a2[v10], v11);
}
else
{
v12 = 1;
}
}
}
}
}
}
}
else
{
print_message(msg_probe_error, *((_QWORD *)&msg_probe_error + 1), "Not a client hello\n", v5, v4);
v12 = -5;
}
}
}
else
{
print_message(msg_probe_info, *((_QWORD *)&msg_probe_info + 1), "Request did not begin with TLS handshake.\n");
v12 = -5;
}
return v12;
}

original_code:
int
parse_tls_header(const struct TLSProtocol *tls_data, const char *data, size_t data_len) {
    char tls_content_type;
    char tls_version_major;
    char tls_version_minor;
    size_t pos = 5;
    size_t len;
    if (data_len < 5)
        return -2;
    tls_content_type = data[0];
    if (tls_content_type != 0x16) {
        print_message(msg_probe_info, "Request did not begin with TLS handshake.\n");
        return -5;
    }
    tls_version_major = data[1];
    tls_version_minor = data[2];
    if (tls_version_major < 3) {
        print_message(msg_probe_error, "Received SSL %d.%d handshake which cannot be parsed.\n",
              tls_version_major, tls_version_minor);
        return -3;
    }
    len = ((unsigned char)data[3] << 8) +
          (unsigned char)data[4] + 5;
    data_len = ((data_len) < (len) ? (data_len) : (len));
    if (data_len < len)
        return -2;
    if (pos + 1 > data_len) {
        return -5;
    }
    if (data[pos] != 0x01) {
        print_message(msg_probe_error, "Not a client hello\n");
        return -5;
    }
    pos += 38;
    if (pos + 1 > data_len)
        return -5;
    len = (unsigned char)data[pos];
    pos += 1 + len;
    if (pos + 2 > data_len)
        return -5;
    len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1];
    pos += 2 + len;
    if (pos + 1 > data_len)
        return -5;
    len = (unsigned char)data[pos];
    pos += 1 + len;
    if (pos == data_len && tls_version_major == 3 && tls_version_minor == 0) {
        print_message(msg_probe_error, "Received SSL 3.0 handshake without extensions\n");
        return -3;
    }
    if (pos + 2 > data_len)
        return -5;
    len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1];
    pos += 2;
    if (pos + len > data_len)
        return -5;
    if (tls_data &&
        (tls_data->match_mode.tls_match_alpn || tls_data->match_mode.tls_match_sni)) {
        return parse_extensions(tls_data, data + pos, len);
    } else {
        return 1;
    }
}

canonical_original_code:
int parse_tls_header(struct TLSProtocol *tls_data, char *data, unsigned long data_len) {
    char tls_content_type;
    char tls_version_major;
    char tls_version_minor;
    unsigned long pos = 5;
    unsigned long len;
    if (data_len < 5)
        return -2;
    tls_content_type = data[0];
    if (tls_content_type != 0x16) {
        print_message(msg_probe_info, "Request did not begin with TLS handshake.\n");
        return -5;
    }
    tls_version_major = data[1];
    tls_version_minor = data[2];
    if (tls_version_major < 3) {
        print_message(msg_probe_error, "Received SSL %d.%d handshake which cannot be parsed.\n",
              tls_version_major, tls_version_minor);
        return -3;
    }
    len = ((unsigned char)data[3] << 8) +
          (unsigned char)data[4] + 5;
    data_len = ((data_len) < (len) ? (data_len) : (len));
    if (data_len < len)
        return -2;
    if (pos + 1 > data_len) {
        return -5;
    }
    if (data[pos] != 0x01) {
        print_message(msg_probe_error, "Not a client hello\n");
        return -5;
    }
    pos += 38;
    if (pos + 1 > data_len)
        return -5;
    len = (unsigned char)data[pos];
    pos += 1 + len;
    if (pos + 2 > data_len)
        return -5;
    len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1];
    pos += 2 + len;
    if (pos + 1 > data_len)
        return -5;
    len = (unsigned char)data[pos];
    pos += 1 + len;
    if (pos == data_len && tls_version_major == 3 && tls_version_minor == 0) {
        print_message(msg_probe_error, "Received SSL 3.0 handshake without extensions\n");
        return -3;
    }
    if (pos + 2 > data_len)
        return -5;
    len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1];
    pos += 2;
    if (pos + len > data_len)
        return -5;
    if (tls_data &&
        (tls_data->match_mode.tls_match_alpn || tls_data->match_mode.tls_match_sni)) {
        return parse_extensions(tls_data, data + pos, len);
    } else {
        return 1;
    }
}


decompiled_code:
_QWORD *new_tls_data()
{
_QWORD *result; // rax

result = malloc(0x20uLL);
if ( !result )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "tls.c", 293LL);
perror("malloc");
exit(1);
}
*result = 0LL;
result[1] = 0LL;
result[2] = 0LL;
result[3] = 0LL;
return result;
}

canonical_decompiled_code:
_QWORD *func5()
{
_QWORD *result; // rax

result = malloc(0x20uLL);
if ( !result )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "tls.c", 293LL);
perror("malloc");
exit(1);
}
*result = 0LL;
result[1] = 0LL;
result[2] = 0LL;
result[3] = 0LL;
return result;
}

original_code:
struct TLSProtocol *
new_tls_data() {
    struct TLSProtocol *tls_data = malloc(sizeof(struct TLSProtocol));
    if (!tls_data) { print_message(msg_system_error, "%s:%d:", "tls.c", 293); perror("malloc"); exit(1); };
    memset(tls_data, 0, sizeof(*tls_data));
    return tls_data;
}

canonical_original_code:
struct TLSProtocol *new_tls_data() {
    struct TLSProtocol *tls_data = malloc(sizeof(struct TLSProtocol));
    if (!tls_data) { print_message(msg_system_error, "%s:%d:", "tls.c", 293); perror("malloc"); exit(1); };
    memset(tls_data, 0, sizeof(*tls_data));
    return tls_data;
}

return_type: struct TLSProtocol { struct TLS_MATCHMODE { int tls_match_sni; int tls_match_alpn; } match_mode; int sni_list_len; char **sni_hostname_list; int alpn_list_len; char **alpn_protocol_list; } *