decompiled_code:
__int64 __fastcall stream_write(__int64 a1, char *a2, unsigned int a3)
{
unsigned int v4; // er13
unsigned int v5; // ebx
unsigned int v6; // edx
int v7; // eax
__int64 v8; // rdx

v4 = a3;
v5 = a3;
while ( 1 )
{
v6 = v5;
if ( *(_DWORD *)(a1 + 28) <= v5 )
v6 = *(_DWORD *)(a1 + 28);
v7 = send(*(_DWORD *)(a1 + 24), a2, (int)v6, 0);
if ( v7 < 0 )
break;
a2 += v7;
v5 -= v7;
if ( !v5 )
return v4;
}
return scarab_session_seterr(*(_QWORD *)(a1 + 8), (unsigned int)(scarab_stream_tcpip[1] + 1), v8);
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1, char *a2, unsigned int a3)
{
unsigned int v4; // er13
unsigned int v5; // ebx
unsigned int v6; // edx
int v7; // eax
__int64 v8; // rdx

v4 = a3;
v5 = a3;
while ( 1 )
{
v6 = v5;
if ( *(_DWORD *)(a1 + 28) <= v5 )
v6 = *(_DWORD *)(a1 + 28);
v7 = send(*(_DWORD *)(a1 + 24), a2, (int)v6, 0);
if ( v7 < 0 )
break;
a2 += v7;
v5 -= v7;
if ( !v5 )
return v4;
}
return scarab_session_seterr(*(_QWORD *)(a1 + 8), (unsigned int)(scarab_stream_tcpip[1] + 1), v8);
}

original_code:
static int stream_write(ScarabStream * stream, const void *buffer, int size) {
 tcpstr *ts = ((tcpstr*)(stream));
 unsigned char *c;
 int r;
 unsigned int left;
 left = (unsigned int)size;
 c = (unsigned char *)buffer;
 do {
        r = send(ts->fd, c, (int)((left) < (ts->packet_size) ? (left) : (ts->packet_size)), 0);
            if (r < 0) {
                return scarab_session_seterr(stream->session, ( (&scarab_stream_tcpip)->err_code_base + (1) ));
            }
  left -= r;
  c += r;
 } while (left);
 return size;
}

canonical_original_code:
static int stream_write(struct __ScarabStream *stream, void *buffer, int size) {
 struct __tcpstr *ts = ((tcpstr*)(stream));
 unsigned char *c;
 int r;
 unsigned int left;
 left = (unsigned int)size;
 c = (unsigned char *)buffer;
 do {
        r = send(ts->fd, c, (int)((left) < (ts->packet_size) ? (left) : (ts->packet_size)), 0);
            if (r < 0) {
                return scarab_session_seterr(stream->session, ( (&scarab_stream_tcpip)->err_code_base + (1) ));
            }
  left -= r;
  c += r;
 } while (left);
 return size;
}

variable_types:
left
unsigned int

user_defined_types: struct __ScarabStreamEngine { int api_version; int err_code_base; int nerr_code; int _pad1; int (*lib_init)(); struct __ScarabStream *(*stream_listen)(struct __ScarabSession *s, char *uri); struct __ScarabStream *(*stream_accept)(struct __ScarabSession *session, char *uri, struct __ScarabStream *binding); struct __ScarabStream *(*stream_connect)(struct __ScarabSession *session, char *uri); int (*stream_close)(struct __ScarabStream *self); int (*write)(struct __ScarabStream *self, void *data, int len); int (*send)(struct __ScarabStream *self); int (*flush)(struct __ScarabStream *self); int (*read)(struct __ScarabStream *self, void *data, int len); int (*seek)(struct __ScarabStream *self, long offset, int origin); long (*tell)(struct __ScarabStream *); char *(*strerr)(int code); char uri_scheme[64]; char engine_author[64]; char engine_name[64]; int (*local_port)(struct __ScarabStream *self); char *(*local_address)(struct __ScarabStream *self); int (*foreign_port)(struct __ScarabStream *self); char *(*foreign_address)(struct __ScarabStream *self); }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }


repo: hahong/pymworks

decompiled_code:
__int64 __fastcall stream_close(__int64 a1)
{
shutdown(*(_DWORD *)(a1 + 24), 2);
close(*(_DWORD *)(a1 + 24));
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1)
{
shutdown(*(_DWORD *)(a1 + 24), 2);
close(*(_DWORD *)(a1 + 24));
return 0LL;
}

original_code:
static int stream_close(ScarabStream * stream) {
 tcpstr *ts = ((tcpstr*)(stream));
 shutdown(ts->fd, 2);
 close(ts->fd);
 return 0;
}

canonical_original_code:
static int stream_close(struct __ScarabStream *stream) {
 struct __tcpstr *ts = ((tcpstr*)(stream));
 shutdown(ts->fd, 2);
 close(ts->fd);
 return 0;
}

variable_types: struct __ScarabStream { struct __ScarabStream *next; struct __ScarabSession { struct __ScarabEncoderEngine { int api_version; int err_code_base; int nerr_code; int _pad1; int (*lib_init)(); int (*session_accept)(struct __ScarabSession *s); int (*session_connect)(struct __ScarabSession *s); int (*session_close)(struct __ScarabSession *s); int (*write_null)(struct __ScarabSession *s); int (*write_integer)(struct __ScarabSession *s, long long value); int (*write_float)(struct __ScarabSession *s, double value); int (*write_float_inf)(struct __ScarabSession *s); int (*write_float_nan)(struct __ScarabSession *s); int (*write_opaque)(struct __ScarabSession *s, char *value, int len); int (*write_list)(struct __ScarabSession *s, struct __ScarabList { int size; struct __ScarabDatum { union { long long integer; double floatp; struct __ScarabOpaque { int size; unsigned char *data; } opaque; struct __ScarabDict { int size; int tablesize; struct __ScarabDatum **keys; struct __ScarabDatum **values; int (*expansion_function)(struct __ScarabDict *dict); } *dict; struct __ScarabList *list; void *p; } data; struct __ScarabDatum *attributes; int type; int ref_count; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *mutex; } **values; } *list); int (*write_dict)(struct __ScarabSession *s, struct __ScarabDict *dict); struct __ScarabDatum *(*read)(struct __ScarabSession *s); int (*seek)(struct __ScarabSession *s, long offset, int origin); long (*tell)(struct __ScarabSession *s); char *(*strerr)(int code); char uri_scheme[64]; char engine_author[64]; char engine_name[64]; } *encoder_engine; void *encoder; char *url; struct __ScarabStream *stream_head; int errcode; int os_errno; int force_buffering; int send_recursion_counter; int send_buffer_position; unsigned char send_buffer[100000000]; unsigned char read_buffer[100000000]; int read_buffer_fill_position; int read_buffer_read_position; } *session; struct __ScarabStreamEngine { int api_version; int err_code_base; int nerr_code; int _pad1; int (*lib_init)(); struct __ScarabStream *(*stream_listen)(struct __ScarabSession *s, char *uri); struct __ScarabStream *(*stream_accept)(struct __ScarabSession *session, char *uri, struct __ScarabStream *binding); struct __ScarabStream *(*stream_connect)(struct __ScarabSession *session, char *uri); int (*stream_close)(struct __ScarabStream *self); int (*write)(struct __ScarabStream *self, void *data, int len); int (*send)(struct __ScarabStream *self); int (*flush)(struct __ScarabStream *self); int (*read)(struct __ScarabStream *self, void *data, int len); int (*seek)(struct __ScarabStream *self, long offset, int origin); long (*tell)(struct __ScarabStream *); char *(*strerr)(int code); char uri_scheme[64]; char engine_author[64]; char engine_name[64]; int (*local_port)(struct __ScarabStream *self); char *(*local_address)(struct __ScarabStream *self); int (*foreign_port)(struct __ScarabStream *self); char *(*foreign_address)(struct __ScarabStream *self); } *engine; } *

variable_types: struct __tcpstr { struct __ScarabStream { struct __ScarabStream *next; struct __ScarabSession { struct __ScarabEncoderEngine { int api_version; int err_code_base; int nerr_code; int _pad1; int (*lib_init)(); int (*session_accept)(struct __ScarabSession *s); int (*session_connect)(struct __ScarabSession *s); int (*session_close)(struct __ScarabSession *s); int (*write_null)(struct __ScarabSession *s); int (*write_integer)(struct __ScarabSession *s, long long value); int (*write_float)(struct __ScarabSession *s, double value); int (*write_float_inf)(struct __ScarabSession *s); int (*write_float_nan)(struct __ScarabSession *s); int (*write_opaque)(struct __ScarabSession *s, char *value, int len); int (*write_list)(struct __ScarabSession *s, struct __ScarabList { int size; struct __ScarabDatum { union { long long integer; double floatp; struct __ScarabOpaque { int size; unsigned char *data; } opaque; struct __ScarabDict { int size; int tablesize; struct __ScarabDatum **keys; struct __ScarabDatum **values; int (*expansion_function)(struct __ScarabDict *dict); } *dict; struct __ScarabList *list; void *p; } data; struct __ScarabDatum *attributes; int type; int ref_count; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *mutex; } **values; } *list); int (*write_dict)(struct __ScarabSession *s, struct __ScarabDict *dict); struct __ScarabDatum *(*read)(struct __ScarabSession *s); int (*seek)(struct __ScarabSession *s, long offset, int origin); long (*tell)(struct __ScarabSession *s); char *(*strerr)(int code); char uri_scheme[64]; char engine_author[64]; char engine_name[64]; } *encoder_engine; void *encoder; char *url; struct __ScarabStream *stream_head; int errcode; int os_errno; int force_buffering; int send_recursion_counter; int send_buffer_position; unsigned char send_buffer[100000000]; unsigned char read_buffer[100000000]; int read_buffer_fill_position; int read_buffer_read_position; } *session; struct __ScarabStreamEngine { int api_version; int err_code_base; int nerr_code; int _pad1; int (*lib_init)(); struct __ScarabStream *(*stream_listen)(struct __ScarabSession *s, char *uri); struct __ScarabStream *(*stream_accept)(struct __ScarabSession *session, char *uri, struct __ScarabStream *binding); struct __ScarabStream *(*stream_connect)(struct __ScarabSession *session, char *uri); int (*stream_close)(struct __ScarabStream *self); int (*write)(struct __ScarabStream *self, void *data, int len); int (*send)(struct __ScarabStream *self); int (*flush)(struct __ScarabStream *self); int (*read)(struct __ScarabStream *self, void *data, int len); int (*seek)(struct __ScarabStream *self, long offset, int origin); long (*tell)(struct __ScarabStream *); char *(*strerr)(int code); char uri_scheme[64]; char engine_author[64]; char engine_name[64]; int (*local_port)(struct __ScarabStream *self); char *(*local_address)(struct __ScarabStream *self); int (*foreign_port)(struct __ScarabStream *self); char *(*foreign_address)(struct __ScarabStream *self); } *engine; } header; int fd; unsigned int packet_size; } *

return_type: int

user_defined_types: struct __ScarabStream { struct __ScarabStream *next; struct __ScarabSession *session; struct __ScarabStreamEngine *engine; }

user_defined_types: struct __tcpstr { struct __ScarabStream header; int fd; unsigned int packet_size; }

user_defined_types: struct __ScarabSession { struct __ScarabEncoderEngine *encoder_engine; void *encoder; char *url; struct __ScarabStream *stream_head; int errcode; int os_errno; int force_buffering; int send_recursion_counter; int send_buffer_position; unsigned char send_buffer[100000000]; unsigned char read_buffer[100000000]; int read_buffer_fill_position; int read_buffer_read_position; }

user_defined_types: struct __ScarabEncoderEngine { int api_version; int err_code_base; int nerr_code; int _pad1; int (*lib_init)(); int (*session_accept)(struct __ScarabSession *s); int (*session_connect)(struct __ScarabSession *s); int (*session_close)(struct __ScarabSession *s); int (*write_null)(struct __ScarabSession *s); int (*write_integer)(struct __ScarabSession *s, long long value); int (*write_float)(struct __ScarabSession *s, double value); int (*write_float_inf)(struct __ScarabSession *s); int (*write_float_nan)(struct __ScarabSession *s); int (*write_opaque)(struct __ScarabSession *s, char *value, int len); int (*write_list)(struct __ScarabSession *s, struct __ScarabList *list); int (*write_dict)(struct __ScarabSession *s, struct __ScarabDict *dict); struct __ScarabDatum *(*read)(struct __ScarabSession *s); int (*seek)(struct __ScarabSession *s, long offset, int origin); long (*tell)(struct __ScarabSession *s); char *(*strerr)(int code); char uri_scheme[64]; char engine_author[64]; char engine_name[64]; }

user_defined_types: struct __ScarabList { int size; struct __ScarabDatum **values; }

user_defined_types: struct __ScarabDatum { union { long long integer; double floatp; struct __ScarabOpaque opaque; struct __ScarabDict *dict; struct __ScarabList *list; void *p; } data; struct __ScarabDatum *attributes; int type; int ref_count; union pthread_mutex_t *mutex; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }


decompiled_code:
__int64 __fastcall stream_connect(__int64 a1, unsigned __int8 *a2)
{
unsigned __int8 *v3; // rbp
unsigned __int64 v4; // rax
int v5; // ebx
__int64 v6; // rdx
unsigned __int8 *v7; // rax
__int64 v8; // rsi
unsigned __int64 v9; // rdx
void *v10; // rax
__int64 v11; // r13
unsigned __int8 *v12; // rbx
__int16 v13; // bp
struct protoent *v14; // rbx
struct hostent *v15; // rax
__int64 v16; // rdx
__int64 v17; // rdx
int v18; // edi
__int64 v19; // rdx
struct sockaddr v21; // [rsp+0h] [rbp-38h] BYREF

v3 = a2;
if ( *a2 == 47 )
{
if ( a2[1] == 47 )
v3 = a2 + 2;
else
v3 = a2 + 1;
}
v4 = *v3;
if ( (unsigned __int8)v4 > 0x3Au )
{
v7 = v3;
}
else
{
v5 = 0;
v6 = 0x400800000000001LL;
if ( _bittest64(&v6, v4) )
goto LABEL_12;
v7 = v3;
}
v8 = 0x400800000000001LL;
do
{
do
{
v5 = 1 - (_DWORD)v3 + (_DWORD)v7++;
v9 = *v7;
}
while ( (unsigned __int8)v9 > 0x3Au );
}
while ( !_bittest64(&v8, v9) );
LABEL_12:
v10 = (void *)scarab_mem_malloc((unsigned int)(v5 + 1));
v11 = (__int64)v10;
if ( v10 )
{
memcpy(v10, v3, v5);
*(_BYTE *)(v11 + v5) = 0;
v12 = &v3[v5];
v13 = 0;
if ( *v12 == 58 )
v13 = atoi((const char *)v12 + 1);
v14 = getprotobyname("tcp");
if ( !v14 )
return 0LL;
*(_QWORD *)&v21.sa_family = 2LL;
*(_QWORD *)&v21.sa_data[6] = 0LL;
*(_WORD *)v21.sa_data = _bswap_16(v13);
v15 = gethostbyname((const char *)v11);
if ( v15 )
{
*(_DWORD *)&v21.sa_data[2] = **(_DWORD **)v15->h_addr_list;
}
else
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 3), v16);
*(_DWORD *)&v21.sa_data[2] = inet_addr((const char *)v11);
if ( !*(_DWORD *)&v21.sa_data[2] )
return 0LL;
}
v11 = scarab_mem_malloc(32LL);
if ( v11 )
{
v18 = socket(2, 1, v14->p_proto);
*(_DWORD *)(v11 + 24) = v18;
if ( v18 < 0 )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 4), v17);
v11 = 0LL;
}
else if ( connect(v18, &v21, 0x10u) < 0 )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 5), v19);
close(*(_DWORD *)(v11 + 24));
v11 = 0LL;
}
else
{
*(_DWORD *)(v11 + 28) = -1;
}
}
}
return v11;
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1, unsigned __int8 *a2)
{
unsigned __int8 *v3; // rbp
unsigned __int64 v4; // rax
int v5; // ebx
__int64 v6; // rdx
unsigned __int8 *v7; // rax
__int64 v8; // rsi
unsigned __int64 v9; // rdx
void *v10; // rax
__int64 v11; // r13
unsigned __int8 *v12; // rbx
__int16 v13; // bp
struct protoent *v14; // rbx
struct hostent *v15; // rax
__int64 v16; // rdx
__int64 v17; // rdx
int v18; // edi
__int64 v19; // rdx
struct sockaddr v21; // [rsp+0h] [rbp-38h] BYREF

v3 = a2;
if ( *a2 == 47 )
{
if ( a2[1] == 47 )
v3 = a2 + 2;
else
v3 = a2 + 1;
}
v4 = *v3;
if ( (unsigned __int8)v4 > 0x3Au )
{
v7 = v3;
}
else
{
v5 = 0;
v6 = 0x400800000000001LL;
if ( _bittest64(&v6, v4) )
goto LABEL_12;
v7 = v3;
}
v8 = 0x400800000000001LL;
do
{
do
{
v5 = 1 - (_DWORD)v3 + (_DWORD)v7++;
v9 = *v7;
}
while ( (unsigned __int8)v9 > 0x3Au );
}
while ( !_bittest64(&v8, v9) );
LABEL_12:
v10 = (void *)scarab_mem_malloc((unsigned int)(v5 + 1));
v11 = (__int64)v10;
if ( v10 )
{
memcpy(v10, v3, v5);
*(_BYTE *)(v11 + v5) = 0;
v12 = &v3[v5];
v13 = 0;
if ( *v12 == 58 )
v13 = atoi((const char *)v12 + 1);
v14 = getprotobyname("tcp");
if ( !v14 )
return 0LL;
*(_QWORD *)&v21.sa_family = 2LL;
*(_QWORD *)&v21.sa_data[6] = 0LL;
*(_WORD *)v21.sa_data = func13(v13);
v15 = gethostbyname((const char *)v11);
if ( v15 )
{
*(_DWORD *)&v21.sa_data[2] = **(_DWORD **)v15->h_addr_list;
}
else
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 3), v16);
*(_DWORD *)&v21.sa_data[2] = inet_addr((const char *)v11);
if ( !*(_DWORD *)&v21.sa_data[2] )
return 0LL;
}
v11 = scarab_mem_malloc(32LL);
if ( v11 )
{
v18 = socket(2, 1, v14->p_proto);
*(_DWORD *)(v11 + 24) = v18;
if ( v18 < 0 )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 4), v17);
v11 = 0LL;
}
else if ( connect(v18, &v21, 0x10u) < 0 )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 5), v19);
close(*(_DWORD *)(v11 + 24));
v11 = 0LL;
}
else
{
*(_DWORD *)(v11 + 28) = -1;
}
}
}
return v11;
}

original_code:
static ScarabStream * stream_connect(ScarabSession * session, const char *uri) {
 tcpstr *ts;
 struct protoent *proto;
 struct hostent *host;
 struct sockaddr_in end_point;
 char *host_name;
 char *c;
 int len;
 short tcp_port = 0;
 len = 0;
 if ('/' == *uri)
  uri++;
 if ('/' == *uri)
  uri++;
 for (c = (char *)uri; *c != 0 && *c != ':' && *c != '/'; c++)
 {
  len++;
 }
 host_name = (char *)scarab_mem_malloc(len + 1);
 if (!host_name)
  return ((void *)0);
 memcpy(host_name, uri, len);
 host_name[len] = 0;
 uri += len;
 if (':' == *uri)
 {
  tcp_port = atoi(uri + 1);
 }
 proto = getprotobyname("tcp");
 if (!proto)
  return ((void *)0);
 memset(&end_point, 0, sizeof(end_point));
 end_point.sin_family = 2;
 end_point.sin_port = htons(tcp_port);
 host = gethostbyname(host_name);
 if (host) {
  memcpy(&end_point.sin_addr, host->h_addr_list[0],
      sizeof(end_point.sin_addr));
 } else {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (3) ));
  end_point.sin_addr.s_addr = inet_addr(host_name);
  if (0 == end_point.sin_addr.s_addr)
   return ((void *)0);
 }
 ts = (tcpstr*)scarab_mem_malloc(sizeof(tcpstr));
 if (!ts)
  return ((void *)0);
 ts->fd = socket(2, SOCK_STREAM, proto->p_proto);
 if (ts->fd < 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (4) ));
  return ((void *)0);
 }
 if (connect(ts->fd, (struct sockaddr *)&end_point,
                                                    sizeof(end_point)) < 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (5) ));
  close(ts->fd);
  return ((void *)0);
 }
 ts->packet_size = (unsigned int)-1;
 return &ts->header;
}

canonical_original_code:
static struct __ScarabStream *stream_connect(struct __ScarabSession *session, char *uri) {
 struct __tcpstr *ts;
 struct protoent *proto;
 struct hostent *host;
 struct sockaddr_in end_point;
 char *host_name;
 char *c;
 int len;
 short tcp_port = 0;
 len = 0;
 if ('/' == *uri)
  uri++;
 if ('/' == *uri)
  uri++;
 for (c = (char *)uri; *c != 0 && *c != ':' && *c != '/'; c++)
 {
  len++;
 }
 host_name = (char *)scarab_mem_malloc(len + 1);
 if (!host_name)
  return ((void *)0);
 memcpy(host_name, uri, len);
 host_name[len] = 0;
 uri += len;
 if (':' == *uri)
 {
  tcp_port = atoi(uri + 1);
 }
 proto = getprotobyname("tcp");
 if (!proto)
  return ((void *)0);
 memset(&end_point, 0, sizeof(end_point));
 end_point.sin_family = 2;
 end_point.sin_port = htons(tcp_port);
 host = gethostbyname(host_name);
 if (host) {
  memcpy(&end_point.sin_addr, host->h_addr_list[0],
      sizeof(end_point.sin_addr));
 } else {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (3) ));
  end_point.sin_addr.s_addr = inet_addr(host_name);
  if (0 == end_point.sin_addr.s_addr)
   return ((void *)0);
 }
 ts = (struct __tcpstr *)scarab_mem_malloc(sizeof(tcpstr));
 if (!ts)
  return ((void *)0);
 ts->fd = socket(2, SOCK_STREAM, proto->p_proto);
 if (ts->fd < 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (4) ));
  return ((void *)0);
 }
 if (connect(ts->fd, (struct sockaddr *)&end_point,
                                                    sizeof(end_point)) < 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (5) ));
  close(ts->fd);
  return ((void *)0);
 }
 ts->packet_size = (unsigned int)-1;
 return &ts->header;
}

variable_types:
session
struct __ScarabSession *

variable_types:
uri
char *

variable_types: struct protoent { char *p_name; char **p_aliases; int p_proto; } *

variable_types: struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; } *

variable_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; }

variable_types:
c
char *

variable_types: len int

return_type: struct __ScarabStream { struct __ScarabStream *next; struct __ScarabSession { struct __ScarabEncoderEngine { int api_version; int err_code_base; int nerr_code; int _pad1; int (*lib_init)(); int (*session_accept)(struct __ScarabSession *s); int (*session_connect)(struct __ScarabSession *s); int (*session_close)(struct __ScarabSession *s); int (*write_null)(struct __ScarabSession *s); int (*write_integer)(struct __ScarabSession *s, long long value); int (*write_float)(struct __ScarabSession *s, double value); int (*write_float_inf)(struct __ScarabSession *s); int (*write_float_nan)(struct __ScarabSession *s); int (*write_opaque)(struct __ScarabSession *s, char *value, int len); int (*write_list)(struct __ScarabSession *s, struct __ScarabList { int size; struct __ScarabDatum { union { long long integer; double floatp; struct __ScarabOpaque { int size; unsigned char *data; } opaque; struct __ScarabDict { int size; int tablesize; struct __ScarabDatum **keys; struct __ScarabDatum **values; int (*expansion_function)(struct __ScarabDict *dict); } *dict; struct __ScarabList *list; void *p; } data; struct __ScarabDatum *attributes; int type; int ref_count; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *mutex; } **values; } *list); int (*write_dict)(struct __ScarabSession *s, struct __ScarabDict *dict); struct __ScarabDatum *(*read)(struct __ScarabSession *s); int (*seek)(struct __ScarabSession *s, long offset, int origin); long (*tell)(struct __ScarabSession *s); char *(*strerr)(int code); char uri_scheme[64]; char engine_author[64]; char engine_name[64]; } *encoder_engine; void *encoder; char *url; struct __ScarabStream *stream_head; int errcode; int os_errno; int force_buffering; int send_recursion_counter; int send_buffer_position; unsigned char send_buffer[100000000]; unsigned char read_buffer[100000000]; int read_buffer_fill_position; int read_buffer_read_position; } *session; struct __ScarabStreamEngine { int api_version; int err_code_base; int nerr_code; int _pad1; int (*lib_init)(); struct __ScarabStream *(*stream_listen)(struct __ScarabSession *s, char *uri); struct __ScarabStream *(*stream_accept)(struct __ScarabSession *session, char *uri, struct __ScarabStream *binding); struct __ScarabStream *(*stream_connect)(struct __ScarabSession *session, char *uri); int (*stream_close)(struct __ScarabStream *self); int (*write)(struct __ScarabStream *self, void *data, int len); int (*send)(struct __ScarabStream *self); int (*flush)(struct __ScarabStream *self); int (*read)(struct __ScarabStream *self, void *data, int len); int (*seek)(struct __ScarabStream *self, long offset, int origin); long (*tell)(struct __ScarabStream *); char *(*strerr)(int code); char uri_scheme[64]; char engine_author[64]; char engine_name[64]; int (*local_port)(struct __ScarabStream *self); char *(*local_address)(struct __ScarabStream *self); int (*foreign_port)(struct __ScarabStream *self); char *(*foreign_address)(struct __ScarabStream *self); } *engine; } *

user_defined_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr sin_addr; unsigned char sin_zero[-1]; }

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


decompiled_code:
__int64 __fastcall stream_accept(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v4; // rbx
int v5; // eax
__int64 v6; // rdx
socklen_t addr_len; // [rsp+Ch] [rbp-2Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-28h] BYREF

*(_QWORD *)&addr.sa_family = 0LL;
*(_QWORD *)&addr.sa_data[6] = 0LL;
addr_len = 16;
v4 = scarab_mem_malloc(32LL);
if ( v4 )
{
v5 = accept(*(_DWORD *)(a3 + 24), &addr, &addr_len);
*(_DWORD *)(v4 + 24) = v5;
if ( v5 < 0 )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 5), v6);
v4 = 0LL;
}
else
{
*(_DWORD *)(v4 + 28) = -1;
}
}
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v4; // rbx
int v5; // eax
__int64 v6; // rdx
socklen_t addr_len; // [rsp+Ch] [rbp-2Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-28h] BYREF

*(_QWORD *)&addr.sa_family = 0LL;
*(_QWORD *)&addr.sa_data[6] = 0LL;
addr_len = 16;
v4 = scarab_mem_malloc(32LL);
if ( v4 )
{
v5 = accept(*(_DWORD *)(a3 + 24), &addr, &addr_len);
*(_DWORD *)(v4 + 24) = v5;
if ( v5 < 0 )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 5), v6);
v4 = 0LL;
}
else
{
*(_DWORD *)(v4 + 28) = -1;
}
}
return v4;
}

original_code:
static ScarabStream *
stream_accept(ScarabSession * session,
     const char *uri, ScarabStream * binding) {
 tcpstr *ts;
 tcpstr *bd;
 struct sockaddr end_point;
 socklen_t len;
 bd = ((tcpstr*)(binding));
 memset(&end_point, 0, sizeof(end_point));
 len = sizeof(end_point);
 ts = (tcpstr*)scarab_mem_malloc(sizeof(tcpstr));
 if (!ts)
  return ((void *)0);
 ts->fd = accept(bd->fd, (struct sockaddr *)&end_point, (socklen_t*)(&len));
 if (ts->fd < 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (5) ));
  return ((void *)0);
 }
 ts->packet_size = (unsigned int)-1;
 return &ts->header;
}

canonical_original_code:
static struct __ScarabStream *stream_accept(struct __ScarabSession *session, char *uri, struct __ScarabStream *binding) {
 struct __tcpstr *ts;
 struct __tcpstr *bd;
 struct sockaddr end_point;
 unsigned int len;
 bd = ((struct __tcpstr *)(binding));
 memset(&end_point, 0, sizeof(end_point));
 len = sizeof(end_point);
 ts = (struct __tcpstr *)scarab_mem_malloc(sizeof(tcpstr));
 if (!ts)
  return ((void *)0);
 ts->fd = accept(bd->fd, (struct sockaddr *)&end_point, (unsigned int *)(&len));
 if (ts->fd < 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (5) ));
  return ((void *)0);
 }
 ts->packet_size = (unsigned int)-1;
 return &ts->header;
}

variable_types:
binding
struct __ScarabStream *

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

variable_types:
len
unsigned int

user_defined_types: struct __ScarabOpaque { int size; unsigned char *data; }

user_defined_types: struct __ScarabDict { int size; int tablesize; struct __ScarabDatum **keys; struct __ScarabDatum **values; int (*expansion_function)(struct __ScarabDict *dict); }

user_defined_types: struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; }


decompiled_code:
__int64 __fastcall stream_bind(__int64 a1, unsigned __int8 *a2)
{
unsigned __int8 *v3; // rbp
unsigned __int64 v4; // rax
int v5; // ebx
__int64 v6; // rdx
unsigned __int8 *v7; // rax
__int64 v8; // rsi
unsigned __int64 v9; // rdx
void *v10; // rax
__int64 v11; // r13
unsigned __int8 *v12; // rbx
__int16 v13; // bp
struct protoent *v14; // rbx
struct hostent *v15; // rax
__int64 v16; // rdx
unsigned int v17; // eax
__int64 v18; // rdi
__int64 v19; // rdx
int v20; // edi
__int64 v21; // rdx
__int64 v22; // rdx
in_addr_t v24; // eax
struct sockaddr v25; // [rsp+0h] [rbp-38h] BYREF

v3 = a2;
if ( *a2 == 47 )
{
if ( a2[1] == 47 )
v3 = a2 + 2;
else
v3 = a2 + 1;
}
v4 = *v3;
if ( (unsigned __int8)v4 > 0x3Au )
{
v7 = v3;
}
else
{
v5 = 0;
v6 = 0x400800000000001LL;
if ( _bittest64(&v6, v4) )
goto LABEL_12;
v7 = v3;
}
v8 = 0x400800000000001LL;
do
{
do
{
v5 = 1 - (_DWORD)v3 + (_DWORD)v7++;
v9 = *v7;
}
while ( (unsigned __int8)v9 > 0x3Au );
}
while ( !_bittest64(&v8, v9) );
LABEL_12:
v10 = (void *)scarab_mem_malloc((unsigned int)(v5 + 1));
v11 = (__int64)v10;
if ( v10 )
{
memcpy(v10, v3, v5);
*(_BYTE *)(v11 + v5) = 0;
v12 = &v3[v5];
v13 = 0;
if ( *v12 == 58 )
v13 = atoi((const char *)v12 + 1);
v14 = getprotobyname("tcp");
if ( v14 )
{
*(_QWORD *)&v25.sa_family = 2LL;
*(_QWORD *)&v25.sa_data[6] = 0LL;
*(_WORD *)v25.sa_data = _bswap_16(v13);
v15 = gethostbyname((const char *)v11);
if ( v15 )
{
*(_DWORD *)&v25.sa_data[2] = **(_DWORD **)v15->h_addr_list;
}
else
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 3), v16);
v24 = inet_addr((const char *)v11);
if ( v24 )
*(_DWORD *)&v25.sa_data[2] = v24;
else
*(_DWORD *)&v25.sa_data[2] = _bswap_32(0);
}
v11 = scarab_mem_malloc(32LL);
if ( v11 )
{
v17 = socket(2, 1, v14->p_proto);
v18 = v17;
*(_DWORD *)(v11 + 24) = v17;
if ( setSocketOptionFlag(v17, 2) >= 0 || (unsigned int)scarab_os_geterr(v18, 2LL) == 92 )
{
v20 = *(_DWORD *)(v11 + 24);
if ( v20 < 0 )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 4), v19);
v11 = 0LL;
}
else if ( bind(v20, &v25, 0x10u) < 0 )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 6), v21);
close(*(_DWORD *)(v11 + 24));
v11 = 0LL;
}
else if ( listen(*(_DWORD *)(v11 + 24), 5) )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 7), v22);
close(*(_DWORD *)(v11 + 24));
v11 = 0LL;
}
}
else
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 4), v19);
close(*(_DWORD *)(v11 + 24));
v11 = 0LL;
}
}
}
else
{
v11 = 0LL;
}
}
return v11;
}

canonical_decompiled_code:
__int64 __fastcall func18(__int64 a1, unsigned __int8 *a2)
{
unsigned __int8 *v3; // rbp
unsigned __int64 v4; // rax
int v5; // ebx
__int64 v6; // rdx
unsigned __int8 *v7; // rax
__int64 v8; // rsi
unsigned __int64 v9; // rdx
void *v10; // rax
__int64 v11; // r13
unsigned __int8 *v12; // rbx
__int16 v13; // bp
struct protoent *v14; // rbx
struct hostent *v15; // rax
__int64 v16; // rdx
unsigned int v17; // eax
__int64 v18; // rdi
__int64 v19; // rdx
int v20; // edi
__int64 v21; // rdx
__int64 v22; // rdx
in_addr_t v24; // eax
struct sockaddr v25; // [rsp+0h] [rbp-38h] BYREF

v3 = a2;
if ( *a2 == 47 )
{
if ( a2[1] == 47 )
v3 = a2 + 2;
else
v3 = a2 + 1;
}
v4 = *v3;
if ( (unsigned __int8)v4 > 0x3Au )
{
v7 = v3;
}
else
{
v5 = 0;
v6 = 0x400800000000001LL;
if ( _bittest64(&v6, v4) )
goto LABEL_12;
v7 = v3;
}
v8 = 0x400800000000001LL;
do
{
do
{
v5 = 1 - (_DWORD)v3 + (_DWORD)v7++;
v9 = *v7;
}
while ( (unsigned __int8)v9 > 0x3Au );
}
while ( !_bittest64(&v8, v9) );
LABEL_12:
v10 = (void *)scarab_mem_malloc((unsigned int)(v5 + 1));
v11 = (__int64)v10;
if ( v10 )
{
memcpy(v10, v3, v5);
*(_BYTE *)(v11 + v5) = 0;
v12 = &v3[v5];
v13 = 0;
if ( *v12 == 58 )
v13 = atoi((const char *)v12 + 1);
v14 = getprotobyname("tcp");
if ( v14 )
{
*(_QWORD *)&v25.sa_family = 2LL;
*(_QWORD *)&v25.sa_data[6] = 0LL;
*(_WORD *)v25.sa_data = func13(v13);
v15 = gethostbyname((const char *)v11);
if ( v15 )
{
*(_DWORD *)&v25.sa_data[2] = **(_DWORD **)v15->h_addr_list;
}
else
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 3), v16);
v24 = inet_addr((const char *)v11);
if ( v24 )
*(_DWORD *)&v25.sa_data[2] = v24;
else
*(_DWORD *)&v25.sa_data[2] = func16(0);
}
v11 = scarab_mem_malloc(32LL);
if ( v11 )
{
v17 = socket(2, 1, v14->p_proto);
v18 = v17;
*(_DWORD *)(v11 + 24) = v17;
if ( func17(v17, 2) >= 0 || (unsigned int)scarab_os_geterr(v18, 2LL) == 92 )
{
v20 = *(_DWORD *)(v11 + 24);
if ( v20 < 0 )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 4), v19);
v11 = 0LL;
}
else if ( bind(v20, &v25, 0x10u) < 0 )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 6), v21);
close(*(_DWORD *)(v11 + 24));
v11 = 0LL;
}
else if ( listen(*(_DWORD *)(v11 + 24), 5) )
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 7), v22);
close(*(_DWORD *)(v11 + 24));
v11 = 0LL;
}
}
else
{
scarab_session_seterr(a1, (unsigned int)(scarab_stream_tcpip[1] + 4), v19);
close(*(_DWORD *)(v11 + 24));
v11 = 0LL;
}
}
}
else
{
v11 = 0LL;
}
}
return v11;
}

original_code:
static ScarabStream * stream_bind(ScarabSession * session, const char *uri) {
 tcpstr *ts;
 struct protoent *proto;
 struct hostent *host;
 struct sockaddr_in end_point;
 char *host_name;
 char *c;
 int len;
 short tcp_port = 0;
 len = 0;
 if ('/' == *uri)
  uri++;
 if ('/' == *uri)
  uri++;
 for (c = (char *)uri; *c != 0 && *c != ':' && *c != '/'; c++) {
  len++;
 }
 host_name = (char*)scarab_mem_malloc(len + 1);
 if (!host_name)
  return ((void *)0);
 memcpy(host_name, uri, len);
 host_name[len] = 0;
 uri += len;
 if (':' == *uri) {
  tcp_port = atoi(uri + 1);
 }
 proto = getprotobyname("tcp");
 if (!proto)
  return ((void *)0);
 memset(&end_point, 0, sizeof(end_point));
 end_point.sin_family = 2;
 end_point.sin_port = htons(tcp_port);
 host = gethostbyname(host_name);
 if (host) {
  memcpy(&end_point.sin_addr, host->h_addr_list[0],
                                                 sizeof(end_point.sin_addr));
 } else {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (3) ));
  end_point.sin_addr.s_addr = inet_addr(host_name);
  if (0 == end_point.sin_addr.s_addr)
   end_point.sin_addr.s_addr = htonl(((in_addr_t) 0x00000000));
 }
 ts = (tcpstr*)scarab_mem_malloc(sizeof(tcpstr));
 if (!ts)
  return ((void *)0);
    ts->fd = socket(2, SOCK_STREAM, proto->p_proto);
    if(setSocketOptionFlag(ts->fd, 2) < 0) {
        if(scarab_os_geterr() != 92) {
            scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (4) ));
            close(ts->fd);
            return ((void *)0);
        }
    }
 if (ts->fd < 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (4) ));
  return ((void *)0);
 }
 if (bind(ts->fd, (struct sockaddr *)&end_point, sizeof(end_point)) < 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (6) ));
  close(ts->fd);
  return ((void *)0);
 }
 if (listen(ts->fd, 5) != 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (7) ));
  close(ts->fd);
  return ((void *)0);
 }
 return &ts->header;
}

canonical_original_code:
static struct __ScarabStream *stream_bind(struct __ScarabSession *session, char *uri) {
 struct __tcpstr *ts;
 struct protoent *proto;
 struct hostent *host;
 struct sockaddr_in end_point;
 char *host_name;
 char *c;
 int len;
 short tcp_port = 0;
 len = 0;
 if ('/' == *uri)
  uri++;
 if ('/' == *uri)
  uri++;
 for (c = (char *)uri; *c != 0 && *c != ':' && *c != '/'; c++) {
  len++;
 }
 host_name = (char *)scarab_mem_malloc(len + 1);
 if (!host_name)
  return ((void *)0);
 memcpy(host_name, uri, len);
 host_name[len] = 0;
 uri += len;
 if (':' == *uri) {
  tcp_port = atoi(uri + 1);
 }
 proto = getprotobyname("tcp");
 if (!proto)
  return ((void *)0);
 memset(&end_point, 0, sizeof(end_point));
 end_point.sin_family = 2;
 end_point.sin_port = htons(tcp_port);
 host = gethostbyname(host_name);
 if (host) {
  memcpy(&end_point.sin_addr, host->h_addr_list[0],
                                                 sizeof(end_point.sin_addr));
 } else {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (3) ));
  end_point.sin_addr.s_addr = inet_addr(host_name);
  if (0 == end_point.sin_addr.s_addr)
   end_point.sin_addr.s_addr = htonl(((unsigned int) 0x00000000));
 }
 ts = (struct __tcpstr *)scarab_mem_malloc(sizeof(tcpstr));
 if (!ts)
  return ((void *)0);
    ts->fd = socket(2, SOCK_STREAM, proto->p_proto);
    if(setSocketOptionFlag(ts->fd, 2) < 0) {
        if(scarab_os_geterr() != 92) {
            scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (4) ));
            close(ts->fd);
            return ((void *)0);
        }
    }
 if (ts->fd < 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (4) ));
  return ((void *)0);
 }
 if (bind(ts->fd, (struct sockaddr *)&end_point, sizeof(end_point)) < 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (6) ));
  close(ts->fd);
  return ((void *)0);
 }
 if (listen(ts->fd, 5) != 0) {
  scarab_session_seterr(session, ( (&scarab_stream_tcpip)->err_code_base + (7) ));
  close(ts->fd);
  return ((void *)0);
 }
 return &ts->header;
}

user_defined_types: struct protoent { char *p_name; char **p_aliases; int p_proto; }

user_defined_types: struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; }


original_code:
int
scarab_hash(ScarabDatum *datum, int modulo, int atry)
{
 int hv = 0;
 int i = 0;
 int s = 0;
 switch (datum->type)
    {
    case 3:
  hv = atry*atry;
  break;
    case 4:
  hv = atry;
  break;
    case 1:
    case 2:
  hv = (int)datum->data.integer;
  break;
    case 7:
  s = datum->data.opaque.size;
  for (i = 4*atry; i< ((s > (4*atry+4)) ? (4*atry+4) : s); i++)
  {
   hv <<= 8;
   hv += datum->data.opaque.data[i];
  }
  break;
    default:
  hv = datum->data.integer * (atry+1);
    }
 return hv % modulo;
}

canonical_original_code:
int scarab_hash(struct __ScarabDatum *datum, int modulo, int atry)
{
 int hv = 0;
 int i = 0;
 int s = 0;
 switch (datum->type)
    {
    case 3:
  hv = atry*atry;
  break;
    case 4:
  hv = atry;
  break;
    case 1:
    case 2:
  hv = (int)datum->data.integer;
  break;
    case 7:
  s = datum->data.opaque.size;
  for (i = 4*atry; i< ((s > (4*atry+4)) ? (4*atry+4) : s); i++)
  {
   hv <<= 8;
   hv += datum->data.opaque.data[i];
  }
  break;
    default:
  hv = datum->data.integer * (atry+1);
    }
 return hv % modulo;
}

variable_types: struct __ScarabDatum { union { long long integer; double floatp; struct __ScarabOpaque { int size; unsigned char *data; } opaque; struct __ScarabDict { int size; int tablesize; struct __ScarabDatum **keys; struct __ScarabDatum **values; int (*expansion_function)(struct __ScarabDict *dict); } *dict; struct __ScarabList { int size; struct __ScarabDatum **values; } *list; void *p; } data; struct __ScarabDatum *attributes; int type; int ref_count; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *mutex; } *

variable_types: modulo int

variable_types: atry int

variable_types: hv int

variable_types: i int

variable_types: s int


decompiled_code:
_BOOL8 __fastcall scarab_equals(__int64 a1, __int64 a2)
{
int v2; // edx
_BOOL8 result; // rax
int v4; // edx
__int64 v5; // rdi
__int64 i; // rax

if ( !a1 || !a2 )
return 0LL;
v2 = *(_DWORD *)(a1 + 24);
result = 0LL;
if ( v2 == *(_DWORD *)(a2 + 24) )
{
switch ( v2 )
{
case 0:
case 3:
case 4:
result = 1LL;
break;
case 1:
result = *(_QWORD *)a1 == *(_QWORD *)a2;
break;
case 2:
result = *(double *)a1 == *(double *)a2;
break;
case 7:
v4 = *(_DWORD *)a1;
result = 0LL;
if ( *(_DWORD *)a1 == *(_DWORD *)a2 )
{
if ( v4 <= 0 )
{
result = 1LL;
}
else
{
v5 = *(_QWORD *)(a1 + 8);
for ( i = 0LL; *(_BYTE *)(v5 + i) == *(_BYTE *)(*(_QWORD *)(a2 + 8) + i); ++i )
{
if ( i == v4 - 1 )
return 1LL;
}
result = 0LL;
}
}
break;
default:
result = *(_QWORD *)a1 == *(_QWORD *)a2;
break;
}
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(__int64 a1, __int64 a2)
{
int v2; // edx
_BOOL8 result; // rax
int v4; // edx
__int64 v5; // rdi
__int64 i; // rax

if ( !a1 || !a2 )
return 0LL;
v2 = *(_DWORD *)(a1 + 24);
result = 0LL;
if ( v2 == *(_DWORD *)(a2 + 24) )
{
switch ( v2 )
{
case 0:
case 3:
case 4:
result = 1LL;
break;
case 1:
result = *(_QWORD *)a1 == *(_QWORD *)a2;
break;
case 2:
result = *(double *)a1 == *(double *)a2;
break;
case 7:
v4 = *(_DWORD *)a1;
result = 0LL;
if ( *(_DWORD *)a1 == *(_DWORD *)a2 )
{
if ( v4 <= 0 )
{
result = 1LL;
}
else
{
v5 = *(_QWORD *)(a1 + 8);
for ( i = 0LL; *(_BYTE *)(v5 + i) == *(_BYTE *)(*(_QWORD *)(a2 + 8) + i); ++i )
{
if ( i == v4 - 1 )
return 1LL;
}
result = 0LL;
}
}
break;
default:
result = *(_QWORD *)a1 == *(_QWORD *)a2;
break;
}
}
return result;
}

original_code:
int
scarab_equals(ScarabDatum *datum1, ScarabDatum *datum2)
{
 int i;
 int s1;
 int s2;
 ScarabOpaque *o1;
 ScarabOpaque *o2;
 if (datum1 != ((void *)0)
  && datum2 != ((void *)0)
  && datum1->type == datum2->type)
    {
  switch (datum1->type)
  {
  case 0:
  case 4:
  case 3:
   return 1;
  case 7:
   o1 = &datum1->data.opaque;
   o2 = &datum2->data.opaque;
   s1 = o1->size;
   s2 = o2->size;
   if (s1 != s2)
    return 0;
   for (i = 0; i < s1; i++)
   {
    if (o1->data[i] != o2->data[i])
     return 0;
   }
   return 1;
   break;
  case 1:
   return datum1->data.integer == datum2->data.integer;
  case 2:
   return datum1->data.floatp == datum2->data.floatp;
  default:
   return datum1->data.p == datum2->data.p;
  }
    }
 return 0;
}

canonical_original_code:
int scarab_equals(struct __ScarabDatum *datum1, struct __ScarabDatum *datum2)
{
 int i;
 int s1;
 int s2;
 struct __ScarabOpaque *o1;
 struct __ScarabOpaque *o2;
 if (datum1 != ((void *)0)
  && datum2 != ((void *)0)
  && datum1->type == datum2->type)
    {
  switch (datum1->type)
  {
  case 0:
  case 4:
  case 3:
   return 1;
  case 7:
   o1 = &datum1->data.opaque;
   o2 = &datum2->data.opaque;
   s1 = o1->size;
   s2 = o2->size;
   if (s1 != s2)
    return 0;
   for (i = 0; i < s1; i++)
   {
    if (o1->data[i] != o2->data[i])
     return 0;
   }
   return 1;
   break;
  case 1:
   return datum1->data.integer == datum2->data.integer;
  case 2:
   return datum1->data.floatp == datum2->data.floatp;
  default:
   return datum1->data.p == datum2->data.p;
  }
    }
 return 0;
}

variable_types: struct __ScarabOpaque { int size; unsigned char *data; } *


decompiled_code:
void scarab_mem_init()
{
;
}

canonical_decompiled_code:
void func0()
{
;
}

original_code:
void scarab_mem_init(void)
{
}

canonical_original_code:
void scarab_mem_init()
{
}

return_type: void


decompiled_code:
void *__fastcall scarab_mem_malloc(int a1)
{
return malloc(a1);
}

canonical_decompiled_code:
void *__fastcall func1(int a1)
{
return malloc(a1);
}

original_code:
void *scarab_mem_malloc(int bytes)
{
 return (void *)malloc(bytes);
}

variable_types: bytes int

return_type: void *


decompiled_code:
void __fastcall scarab_mem_free(void *a1)
{
free(a1);
}

canonical_decompiled_code:
void __fastcall func2(void *a1)
{
free(a1);
}

original_code:
void scarab_mem_free(void *ptr)
{
 free(ptr);
}

variable_types:
ptr
void *


decompiled_code:
void scarab_os_init()
{
;
}

original_code:
void
scarab_os_init()
{
}

canonical_original_code:
void scarab_os_init()
{
}


decompiled_code:
char *__fastcall scarab_os_strerror(int a1)
{
return strerror(a1);
}

canonical_decompiled_code:
char *__fastcall func1(int a1)
{
return strerror(a1);
}

original_code:
const char*
scarab_os_strerror(int err)
{
 return strerror(err);
}

canonical_original_code:
char *scarab_os_strerror(int err)
{
 return strerror(err);
}

variable_types: err int

return_type: char *


decompiled_code:
__int64 scarab_os_geterr()
{
return (unsigned int)*_errno_location();
}

canonical_decompiled_code:
__int64 func2()
{
return (unsigned int)*_errno_location();
}

original_code:
int
scarab_os_geterr()
{
 return (*__errno_location ());
}


decompiled_code:
__int64 __fastcall scarab_list_new(int a1)
{
__int64 v1; // r12
__int64 v2; // rbp
__int64 v3; // rax

v1 = scarab_new_molecular();
v2 = scarab_mem_malloc(16LL);
*(_DWORD *)v2 = a1;
*(_QWORD *)(v2 + 8) = scarab_mem_malloc((unsigned int)(8 * a1));
if ( a1 > 0 )
{
v3 = 0LL;
do
{
*(_QWORD *)(*(_QWORD *)(v2 + 8) + v3) = 0LL;
v3 += 8LL;
}
while ( v3 != 8LL * (unsigned int)a1 );
}
*(_QWORD *)v1 = v2;
*(_DWORD *)(v1 + 24) = 6;
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1)
{
__int64 v1; // r12
__int64 v2; // rbp
__int64 v3; // rax

v1 = scarab_new_molecular();
v2 = scarab_mem_malloc(16LL);
*(_DWORD *)v2 = a1;
*(_QWORD *)(v2 + 8) = scarab_mem_malloc((unsigned int)(8 * a1));
if ( a1 > 0 )
{
v3 = 0LL;
do
{
*(_QWORD *)(*(_QWORD *)(v2 + 8) + v3) = 0LL;
v3 += 8LL;
}
while ( v3 != 8LL * (unsigned int)a1 );
}
*(_QWORD *)v1 = v2;
*(_DWORD *)(v1 + 24) = 6;
return v1;
}

original_code:
ScarabDatum*
scarab_list_new(int initialsize)
{
 int i;
 ScarabDatum *d = scarab_new_molecular();
 ScarabList *list;
 list = (ScarabList*)scarab_mem_malloc(sizeof(ScarabList));
 list->size = initialsize;
 list->values = (ScarabDatum**)scarab_mem_malloc(initialsize * sizeof(void*));
 for (i = 0; i < initialsize; i++)
 {
  list->values[i] = ((void *)0);
 }
 d->data.list = list;
 d->type = 6;
 return d;
}

canonical_original_code:
struct __ScarabDatum *scarab_list_new(int initialsize)
{
 int i;
 struct __ScarabDatum *d = scarab_new_molecular();
 struct __ScarabList *list;
 list = (struct __ScarabList *)scarab_mem_malloc(sizeof(ScarabList));
 list->size = initialsize;
 list->values = (struct __ScarabDatum **)scarab_mem_malloc(initialsize * sizeof(void *));
 for (i = 0; i < initialsize; i++)
 {
  list->values[i] = ((void *)0);
 }
 d->data.list = list;
 d->type = 6;
 return d;
}

variable_types: initialsize int

variable_types: struct __ScarabList { int size; struct __ScarabDatum { union { long long integer; double floatp; struct __ScarabOpaque { int size; unsigned char *data; } opaque; struct __ScarabDict { int size; int tablesize; struct __ScarabDatum **keys; struct __ScarabDatum **values; int (*expansion_function)(struct __ScarabDict *dict); } *dict; struct __ScarabList *list; void *p; } data; struct __ScarabDatum *attributes; int type; int ref_count; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *mutex; } **values; } *

return_type: struct __ScarabDatum { union { long long integer; double floatp; struct __ScarabOpaque { int size; unsigned char *data; } opaque; struct __ScarabDict { int size; int tablesize; struct __ScarabDatum **keys; struct __ScarabDatum **values; int (*expansion_function)(struct __ScarabDict *dict); } *dict; struct __ScarabList { int size; struct __ScarabDatum **values; } *list; void *p; } data; struct __ScarabDatum *attributes; int type; int ref_count; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *mutex; } *


original_code:
ScarabDatum*
scarab_list_put(ScarabDatum *list, int idx, ScarabDatum *val)
{
 scarab_lock_datum(list);
 scarab_lock_datum(val);
 ScarabList *l = list->data.list;
 ScarabDatum *oldval = l->values[idx];
 l->values[idx] = val;
 if(val != ((void *)0)){
  val->ref_count++;
 }
 scarab_unlock_datum(val);
 scarab_unlock_datum(list);
 return oldval;
}

canonical_original_code:
struct __ScarabDatum *scarab_list_put(struct __ScarabDatum *list, int idx, struct __ScarabDatum *val)
{
 scarab_lock_datum(list);
 scarab_lock_datum(val);
 struct __ScarabList *l = list->data.list;
 struct __ScarabDatum *oldval = l->values[idx];
 l->values[idx] = val;
 if(val != ((void *)0)){
  val->ref_count++;
 }
 scarab_unlock_datum(val);
 scarab_unlock_datum(list);
 return oldval;
}

variable_types:
list
struct __ScarabDatum *

variable_types: idx int

variable_types:
val
struct __ScarabDatum *


decompiled_code:
__int64 __fastcall scarab_list_get(__int64 a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // rdx
__int64 v4; // rcx
__int64 v5; // r8
__int64 v6; // r9

scarab_lock_datum(a1);
v2 = *(_QWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 8LL) + 8LL * (int)a2);
scarab_unlock_datum(a1, a2, v3, v4, v5, v6);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // rdx
__int64 v4; // rcx
__int64 v5; // r8
__int64 v6; // r9

scarab_lock_datum(a1);
v2 = *(_QWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 8LL) + 8LL * (int)a2);
scarab_unlock_datum(a1, a2, v3, v4, v5, v6);
return v2;
}

original_code:
ScarabDatum*
scarab_list_get(ScarabDatum *list, int idx)
{
 scarab_lock_datum(list);
 ScarabList *l = list->data.list;
 ScarabDatum *value = l->values[idx];
 scarab_unlock_datum(list);
 return value;
}

canonical_original_code:
struct __ScarabDatum *scarab_list_get(struct __ScarabDatum *list, int idx)
{
 scarab_lock_datum(list);
 struct __ScarabList *l = list->data.list;
 struct __ScarabDatum *value = l->values[idx];
 scarab_unlock_datum(list);
 return value;
}


decompiled_code:
double __fastcall scarab_extract_float(__int64 a1)
{
return **(double **)(a1 + 8);
}

canonical_decompiled_code:
double __fastcall func1(__int64 a1)
{
return **(double **)(a1 + 8);
}

original_code:
double scarab_extract_float(ScarabDatum *datum){
 return *((double *)(datum->data.opaque.data));
}

canonical_original_code:
double scarab_extract_float(struct __ScarabDatum *datum){
 return *((double *)(datum->data.opaque.data));
}

return_type: double


repo: haibbo/improxy

original_code:
void imp_remove_timer(imp_timer **timer)
{
    do { if ((*timer)->link.le_next != ((void *)0)) (*timer)->link.le_next->link.le_prev = (*timer)->link.le_prev; *(*timer)->link.le_prev = (*timer)->link.le_next; } while ( 0);
    free(*timer);
    *timer = ((void *)0);
}

canonical_original_code:
void imp_remove_timer(struct imp_timer **timer)
{
    do { if ((*timer)->link.le_next != ((void *)0)) (*timer)->link.le_next->link.le_prev = (*timer)->link.le_prev; *(*timer)->link.le_prev = (*timer)->link.le_next; } while ( 0);
    free(*timer);
    *timer = ((void *)0);
}

variable_types: struct imp_timer { struct { struct imp_timer *le_next; struct imp_timer **le_prev; } link; struct timeval { long tv_sec; long tv_usec; } tm; struct imp_timer *(*expire)(void *); void *expire_data; } **

user_defined_types: struct imp_timer { struct { struct imp_timer *le_next; struct imp_timer **le_prev; } link; struct timeval tm; struct imp_timer *(*expire)(void *); void *expire_data; }


decompiled_code:
void imp_init_timer()
{
timer_head = 0LL;
}

canonical_decompiled_code:
void func1()
{
timer_head = 0LL;
}

original_code:
void imp_init_timer(void)
{
    do { (&timer_head)->lh_first = ((void *)0); } while ( 0);
}

canonical_original_code:
void imp_init_timer()
{
    do { (&timer_head)->lh_first = ((void *)0); } while ( 0);
}


decompiled_code:
__int64 __fastcall imp_set_timer(__int64 a1, __m128i *a2)
{
__int64 result; // rax
__m128i v3[2]; // [rsp+0h] [rbp-28h] BYREF

if ( !a2 )
return logger_build(1LL, "ERROR", "imp_set_timer", 84LL, "timer is null");
result = get_sysuptime(v3);
if ( (int)result < 0 )
return logger_build(1LL, "ERROR", "imp_set_timer", 89LL, "Can't get time of now");
v3[0].m128i_i64[0] += a1;
a2[1] = _mm_loadu_si128(v3);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __m128i *a2)
{
__int64 result; // rax
__m128i v3[2]; // [rsp+0h] [rbp-28h] BYREF

if ( !a2 )
return logger_build(1LL, "ERROR", "imp_set_timer", 84LL, "timer is null");
result = get_sysuptime(v3);
if ( (int)result < 0 )
return logger_build(1LL, "ERROR", "imp_set_timer", 89LL, "Can't get time of now");
v3[0].m128i_i64[0] += a1;
a2[1] = _mm_loadu_si128(v3);
return result;
}

original_code:
void imp_set_timer(time_t tv_sec, imp_timer *timer)
{
    struct timeval now;
    if(timer == ((void *)0)) {
        logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 84, "timer is null");
        return;
    }
    if(get_sysuptime(&now) < 0) {
        logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 89, "Can't get time of now");
        return;
    }
    now.tv_sec += tv_sec;
    memcpy(&timer->tm, &now, sizeof(struct timeval));
    return;
}

canonical_original_code:
void imp_set_timer(long tv_sec, struct imp_timer *timer)
{
    struct timeval now;
    if(timer == ((void *)0)) {
        logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 84, "timer is null");
        return;
    }
    if(get_sysuptime(&now) < 0) {
        logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 89, "Can't get time of now");
        return;
    }
    now.tv_sec += tv_sec;
    memcpy(&timer->tm, &now, sizeof(struct timeval));
    return;
}

variable_types: struct imp_timer { struct { struct imp_timer *le_next; struct imp_timer **le_prev; } link; struct timeval { long tv_sec; long tv_usec; } tm; struct imp_timer *(*expire)(void *); void *expire_data; } *


decompiled_code:
__int64 __fastcall imp_time_val(__int64 a1, __m128i *a2)
{
__int64 result; // rax
__m128i v3[2]; // [rsp+0h] [rbp-28h] BYREF

result = get_sysuptime(v3);
if ( (int)result < 0 )
return logger_build(1LL, "ERROR", "imp_time_val", 106LL, "Can't get time of now");
v3[0].m128i_i64[0] += a1;
*a2 = _mm_loadu_si128(v3);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __m128i *a2)
{
__int64 result; // rax
__m128i v3[2]; // [rsp+0h] [rbp-28h] BYREF

result = get_sysuptime(v3);
if ( (int)result < 0 )
return logger_build(1LL, "ERROR", "imp_time_val", 106LL, "Can't get time of now");
v3[0].m128i_i64[0] += a1;
*a2 = _mm_loadu_si128(v3);
return result;
}

original_code:
void imp_time_val(time_t tv_sec, struct timeval *result)
{
    struct timeval now;
    if(get_sysuptime(&now) < 0) {
        logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 106, "Can't get time of now");
        return;
    }
    now.tv_sec += tv_sec;
    memcpy(result, &now, sizeof(struct timeval));
    return;
}

canonical_original_code:
void imp_time_val(long tv_sec, struct timeval *result)
{
    struct timeval now;
    if(get_sysuptime(&now) < 0) {
        logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 106, "Can't get time of now");
        return;
    }
    now.tv_sec += tv_sec;
    memcpy(result, &now, sizeof(struct timeval));
    return;
}

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


original_code:
struct timeval* imp_check_timer(void)
{
    static struct timeval returnval;
    imp_timer *mt, *mt_next;
    struct timeval *w = &tm_max;
    struct timeval now;
    int res = 0;
    for (mt = ((&timer_head)->lh_first); mt; mt = mt_next)
    {
        mt_next = ((mt)->link.le_next);
        memset(&now, 0, sizeof(now));
        if ((res = get_sysuptime(&now)) == -1 ){
            returnval.tv_sec = returnval.tv_usec = 0;
            return (&returnval);
        }
        if(((mt->tm).tv_sec == 0 && (mt->tm).tv_usec == 0))
            continue;
        if ((((mt->tm).tv_sec < (now).tv_sec) || (((mt->tm).tv_sec == (now).tv_sec) && ((mt->tm).tv_usec < (now).tv_usec)))) {
            if (mt->expire(mt->expire_data) == ((void *)0)) {
                logger_build(LOG_PRI_DEBUG, "DEBUG", __FUNCTION__, 171, "continue............\n");
                mt_next = ((&timer_head)->lh_first);
                w = &tm_max;
                continue;
            }
        }
        if ((((mt->tm).tv_sec < (*w).tv_sec) || (((mt->tm).tv_sec == (*w).tv_sec) && ((mt->tm).tv_usec < (*w).tv_usec))))
            w = &mt->tm;
    }
    if (((*w).tv_sec == (tm_max).tv_sec && (*w).tv_usec == (tm_max).tv_usec))
        return ((void *)0);
    if ((res = get_sysuptime(&now)) == -1 ){
        returnval.tv_sec = returnval.tv_usec = 0;
        return (&returnval);
    }
    if ((((now).tv_sec < (*w).tv_sec) || (((now).tv_sec == (*w).tv_sec) && ((now).tv_usec < (*w).tv_usec)))){
        memcpy(&returnval, w, sizeof(returnval));
        timeval_sub(w, &now, &returnval);
    }
    else {
        returnval.tv_sec = returnval.tv_usec = 0;
    }
    return &returnval;
}

canonical_original_code:
struct timeval *imp_check_timer()
{
    static struct timeval returnval;
    struct imp_timer *mt; struct imp_timer *mt_next;
    struct timeval *w = &tm_max;
    struct timeval now;
    int res = 0;
    for (mt = ((&timer_head)->lh_first); mt; mt = mt_next)
    {
        mt_next = ((mt)->link.le_next);
        memset(&now, 0, sizeof(now));
        if ((res = get_sysuptime(&now)) == -1 ){
            returnval.tv_sec = returnval.tv_usec = 0;
            return (&returnval);
        }
        if(((mt->tm).tv_sec == 0 && (mt->tm).tv_usec == 0))
            continue;
        if ((((mt->tm).tv_sec < (now).tv_sec) || (((mt->tm).tv_sec == (now).tv_sec) && ((mt->tm).tv_usec < (now).tv_usec)))) {
            if (mt->expire(mt->expire_data) == ((void *)0)) {
                logger_build(LOG_PRI_DEBUG, "DEBUG", __FUNCTION__, 171, "continue............\n");
                mt_next = ((&timer_head)->lh_first);
                w = &tm_max;
                continue;
            }
        }
        if ((((mt->tm).tv_sec < (*w).tv_sec) || (((mt->tm).tv_sec == (*w).tv_sec) && ((mt->tm).tv_usec < (*w).tv_usec))))
            w = &mt->tm;
    }
    if (((*w).tv_sec == (tm_max).tv_sec && (*w).tv_usec == (tm_max).tv_usec))
        return ((void *)0);
    if ((res = get_sysuptime(&now)) == -1 ){
        returnval.tv_sec = returnval.tv_usec = 0;
        return (&returnval);
    }
    if ((((now).tv_sec < (*w).tv_sec) || (((now).tv_sec == (*w).tv_sec) && ((now).tv_usec < (*w).tv_usec)))){
        memcpy(&returnval, w, sizeof(returnval));
        timeval_sub(w, &now, &returnval);
    }
    else {
        returnval.tv_sec = returnval.tv_usec = 0;
    }
    return &returnval;
}

variable_types: res int

return_type: struct timeval { long tv_sec; long tv_usec; } *


decompiled_code:
void __fastcall send_igmp_mld_query(__int64 a1, int a2, _DWORD *a3, __int64 a4, __int64 *a5, unsigned int a6)
{
__int16 v8; // r13
void *v9; // rax
__int64 v10; // r12
int v11; // er14
const char *v12; // r13
const char *v13; // rax
unsigned __int16 v14; // ax
int v15; // er13
unsigned int v16; // ebx
int v17; // er13
int *v18; // rax
char *v19; // rax
unsigned __int64 v20; // r14
unsigned __int16 v21; // ax
char v22; // al
const char *v23; // rax
char v24; // al
int v27; // [rsp+18h] [rbp-C0h]
int fd; // [rsp+1Ch] [rbp-BCh]
__int64 v29[2]; // [rsp+20h] [rbp-B8h] BYREF
__int64 v30; // [rsp+30h] [rbp-A8h] BYREF
int v31; // [rsp+38h] [rbp-A0h]
int v32; // [rsp+3Ch] [rbp-9Ch]
__m128i v33; // [rsp+40h] [rbp-98h]
__int64 v34; // [rsp+50h] [rbp-88h]
struct msghdr addr[2]; // [rsp+60h] [rbp-78h] BYREF

if ( !a1 )
{
logger_build(1LL, "ERROR", "send_igmp_mld_query", 71LL, "p_if is NULL\n");
return;
}
v8 = *(_WORD *)(a1 + 80);
if ( v8 != *(_WORD *)a3 || a4 && v8 != *(_WORD *)a4 )
{
logger_build(1LL, "ERROR", "send_igmp_mld_query", 80LL, "family don't match, can't send igmp query\n");
return;
}
v27 = *(_DWORD *)(a1 + 224);
v9 = malloc(v27);
v10 = (__int64)v9;
if ( !v9 )
{
logger_build(0LL, "FATAL", "send_igmp_mld_query", 87LL, "malloc failed\n");
exit(1);
}
memset(v9, 0, v27);
if ( v8 == 2 )
{
v11 = get_igmp_mld_socket(2LL);
addr[0].msg_name = 0LL;
*(_QWORD *)&addr[0].msg_namelen = 0LL;
v12 = (const char *)imp_pi_ntoa(a3);
v13 = (const char *)imp_pi_ntoa(a1 + 80);
logger_build(4LL, "DEBUG", "send_igmp_mld_query", 101LL, "src = %s dst = %s \n", v13, v12);
logger_build(4LL, "DEBUG", "send_igmp_mld_query", 104LL, "max_len = %d\n", (unsigned int)(v27 - 24));
*(_BYTE *)v10 = 17;
if ( a2 == 1 )
{
if ( !a4 )
{
*(_WORD *)(v10 + 2) = 0;
v22 = *(_BYTE *)(v10 + 8) & 0xF0;
*(_BYTE *)(v10 + 9) = 125;
*(_WORD *)(v10 + 10) = 0;
*(_BYTE *)(v10 + 8) = (8 * (a6 & 1)) | v22 | 2;
v16 = 8;
goto LABEL_24;
}
}
else
{
*(_BYTE *)(v10 + 1) = 100;
if ( !a4 )
goto LABEL_47;
}
v23 = (const char *)imp_pi_ntoa(a4);
logger_build(4LL, "DEBUG", "send_igmp_mld_query", 115LL, "g = %s \n", v23);
*(_DWORD *)(v10 + 4) = *(_DWORD *)(a4 + 4);
*(_BYTE *)(v10 + 1) = 10;
LABEL_47:
*(_WORD *)(v10 + 2) = 0;
v24 = *(_BYTE *)(v10 + 8) & 0xF0;
*(_BYTE *)(v10 + 9) = 125;
*(_WORD *)(v10 + 10) = 0;
*(_BYTE *)(v10 + 8) = (8 * (a6 & 1)) | v24 | 2;
if ( a5 && a2 == 3 )
{
v15 = 0;
while ( 1 )
{
if ( *((_WORD *)a5 + 8) == 2 )
{
if ( !(unsigned int)imp_source_is_scheduled(a5, a6) )
{
a5 = (__int64 *)*a5;
goto LABEL_17;
}
v14 = *(_WORD *)(v10 + 10);
*(_DWORD *)(v10 + 4LL * v14 + 12) = *((_DWORD *)a5 + 5);
*(_WORD *)(v10 + 10) = v14 + 1;
v15 += 4;
}
a5 = (__int64 *)*a5;
LABEL_17:
if ( !a5 || v15 > (unsigned __int64)(v27 - 24 - 4LL) )
goto LABEL_26;
}
}
if ( a2 == 3 )
LABEL_26:
v16 = 4 * *(unsigned __int16 *)(v10 + 10) + 12;
else
v16 = 8;
LABEL_24:
logger_build(4LL, "DEBUG", "send_igmp_mld_query", 155LL, "igh_len = %d\n", v16);
*(_WORD *)(v10 + 2) = in_cusm(v10, v16);
setsockopt(v11, 0, 32, (const void *)(a1 + 84), 4u);
LOWORD(addr[0].msg_name) = 2;
HIDWORD(addr[0].msg_name) = a3[1];
if ( sendto(v11, (const void *)v10, (int)v16, 0, (const struct sockaddr *)addr, 0x10u) == -1 )
logger_build(1LL, "ERROR", "send_igmp_mld_query", 165LL, "sendto failed\n");
goto LABEL_10;
}
if ( v8 == 10 )
{
fd = get_igmp_mld_socket(10LL);
*(_BYTE *)v10 = -126;
*(_BYTE *)(v10 + 1) = 0;
*(_WORD *)(v10 + 2) = 0;
*(_WORD *)(v10 + 4) = _bswap_16(10000);
*(_BYTE *)(v10 + 24) = (8 * (a6 & 1)) | *(_BYTE *)(v10 + 24) & 0xF0 | 2;
*(_BYTE *)(v10 + 25) = 125;
*(_WORD *)(v10 + 26) = 0;
v17 = 24;
if ( a2 != 3 )
{
LABEL_28:
if ( a4 )
{
*(__m128i *)(v10 + 8) = _mm_loadu_si128((const __m128i *)(a4 + 8));
*(_WORD *)(v10 + 4) = _bswap_16(1000);
}
*(_WORD *)(v10 + 2) = in_cusm(v10, 28LL);
v34 = 0LL;
v29[0] = v10;
v29[1] = v17;
*(_QWORD *)&addr[0].msg_namelen = 28LL;
*(_QWORD *)&addr[0].msg_flags = 0LL;
addr[0].msg_name = a3;
addr[0].msg_iov = (struct iovec *)v29;
addr[0].msg_iovlen = 1LL;
addr[0].msg_control = &v30;
addr[0].msg_controllen = 40LL;
v31 = 41;
v32 = 50;
v30 = 36LL;
v34 = *(unsigned int *)(a1 + 212);
v33 = _mm_loadu_si128((const __m128i *)(a1 + 88));
if ( sendmsg(fd, addr, 0) < 0 )
{
v18 = _errno_location();
v19 = strerror(*v18);
logger_build(1LL, "ERROR", "send_igmp_mld_query", 248LL, "mld query: sendmsg failed: %s\n", v19);
}
goto LABEL_10;
}
if ( !a5 )
{
v17 = 28;
goto LABEL_28;
}
v20 = v27 - 48 - 16LL;
if ( v20 <= 0x1B )
{
v17 = 28;
goto LABEL_28;
}
v17 = 28;
while ( 1 )
{
if ( *((_WORD *)a5 + 8) == 10 )
{
if ( !(unsigned int)imp_source_is_scheduled(a5, a6) )
{
a5 = (__int64 *)*a5;
goto LABEL_37;
}
v21 = *(_WORD *)(v10 + 26);
*(__m128i *)(16LL * v21 + v10 + 28) = _mm_loadu_si128((const __m128i *)(a5 + 3));
*(_WORD *)(v10 + 26) = v21 + 1;
v17 += 16;
}
a5 = (__int64 *)*a5;
LABEL_37:
if ( !a5 || v17 > v20 )
goto LABEL_28;
}
}
LABEL_10:
free((void *)v10);
}

canonical_decompiled_code:
void __fastcall func1(__int64 a1, int a2, _DWORD *a3, __int64 a4, __int64 *a5, unsigned int a6)
{
__int16 v8; // r13
void *v9; // rax
__int64 v10; // r12
int v11; // er14
const char *v12; // r13
const char *v13; // rax
unsigned __int16 v14; // ax
int v15; // er13
unsigned int v16; // ebx
int v17; // er13
int *v18; // rax
char *v19; // rax
unsigned __int64 v20; // r14
unsigned __int16 v21; // ax
char v22; // al
const char *v23; // rax
char v24; // al
int v27; // [rsp+18h] [rbp-C0h]
int fd; // [rsp+1Ch] [rbp-BCh]
__int64 v29[2]; // [rsp+20h] [rbp-B8h] BYREF
__int64 v30; // [rsp+30h] [rbp-A8h] BYREF
int v31; // [rsp+38h] [rbp-A0h]
int v32; // [rsp+3Ch] [rbp-9Ch]
__m128i v33; // [rsp+40h] [rbp-98h]
__int64 v34; // [rsp+50h] [rbp-88h]
struct msghdr addr[2]; // [rsp+60h] [rbp-78h] BYREF

if ( !a1 )
{
logger_build(1LL, "ERROR", "send_igmp_mld_query", 71LL, "p_if is NULL\n");
return;
}
v8 = *(_WORD *)(a1 + 80);
if ( v8 != *(_WORD *)a3 || a4 && v8 != *(_WORD *)a4 )
{
logger_build(1LL, "ERROR", "send_igmp_mld_query", 80LL, "family don't match, can't send igmp query\n");
return;
}
v27 = *(_DWORD *)(a1 + 224);
v9 = malloc(v27);
v10 = (__int64)v9;
if ( !v9 )
{
logger_build(0LL, "FATAL", "send_igmp_mld_query", 87LL, "malloc failed\n");
exit(1);
}
memset(v9, 0, v27);
if ( v8 == 2 )
{
v11 = get_igmp_mld_socket(2LL);
addr[0].msg_name = 0LL;
*(_QWORD *)&addr[0].msg_namelen = 0LL;
v12 = (const char *)imp_pi_ntoa(a3);
v13 = (const char *)imp_pi_ntoa(a1 + 80);
logger_build(4LL, "DEBUG", "send_igmp_mld_query", 101LL, "src = %s dst = %s \n", v13, v12);
logger_build(4LL, "DEBUG", "send_igmp_mld_query", 104LL, "max_len = %d\n", (unsigned int)(v27 - 24));
*(_BYTE *)v10 = 17;
if ( a2 == 1 )
{
if ( !a4 )
{
*(_WORD *)(v10 + 2) = 0;
v22 = *(_BYTE *)(v10 + 8) & 0xF0;
*(_BYTE *)(v10 + 9) = 125;
*(_WORD *)(v10 + 10) = 0;
*(_BYTE *)(v10 + 8) = (8 * (a6 & 1)) | v22 | 2;
v16 = 8;
goto LABEL_24;
}
}
else
{
*(_BYTE *)(v10 + 1) = 100;
if ( !a4 )
goto LABEL_47;
}
v23 = (const char *)imp_pi_ntoa(a4);
logger_build(4LL, "DEBUG", "send_igmp_mld_query", 115LL, "g = %s \n", v23);
*(_DWORD *)(v10 + 4) = *(_DWORD *)(a4 + 4);
*(_BYTE *)(v10 + 1) = 10;
LABEL_47:
*(_WORD *)(v10 + 2) = 0;
v24 = *(_BYTE *)(v10 + 8) & 0xF0;
*(_BYTE *)(v10 + 9) = 125;
*(_WORD *)(v10 + 10) = 0;
*(_BYTE *)(v10 + 8) = (8 * (a6 & 1)) | v24 | 2;
if ( a5 && a2 == 3 )
{
v15 = 0;
while ( 1 )
{
if ( *((_WORD *)a5 + 8) == 2 )
{
if ( !(unsigned int)imp_source_is_scheduled(a5, a6) )
{
a5 = (__int64 *)*a5;
goto LABEL_17;
}
v14 = *(_WORD *)(v10 + 10);
*(_DWORD *)(v10 + 4LL * v14 + 12) = *((_DWORD *)a5 + 5);
*(_WORD *)(v10 + 10) = v14 + 1;
v15 += 4;
}
a5 = (__int64 *)*a5;
LABEL_17:
if ( !a5 || v15 > (unsigned __int64)(v27 - 24 - 4LL) )
goto LABEL_26;
}
}
if ( a2 == 3 )
LABEL_26:
v16 = 4 * *(unsigned __int16 *)(v10 + 10) + 12;
else
v16 = 8;
LABEL_24:
logger_build(4LL, "DEBUG", "send_igmp_mld_query", 155LL, "igh_len = %d\n", v16);
*(_WORD *)(v10 + 2) = in_cusm(v10, v16);
setsockopt(v11, 0, 32, (const void *)(a1 + 84), 4u);
LOWORD(addr[0].msg_name) = 2;
HIDWORD(addr[0].msg_name) = a3[1];
if ( sendto(v11, (const void *)v10, (int)v16, 0, (const struct sockaddr *)addr, 0x10u) == -1 )
logger_build(1LL, "ERROR", "send_igmp_mld_query", 165LL, "sendto failed\n");
goto LABEL_10;
}
if ( v8 == 10 )
{
fd = get_igmp_mld_socket(10LL);
*(_BYTE *)v10 = -126;
*(_BYTE *)(v10 + 1) = 0;
*(_WORD *)(v10 + 2) = 0;
*(_WORD *)(v10 + 4) = func0(10000);
*(_BYTE *)(v10 + 24) = (8 * (a6 & 1)) | *(_BYTE *)(v10 + 24) & 0xF0 | 2;
*(_BYTE *)(v10 + 25) = 125;
*(_WORD *)(v10 + 26) = 0;
v17 = 24;
if ( a2 != 3 )
{
LABEL_28:
if ( a4 )
{
*(__m128i *)(v10 + 8) = _mm_loadu_si128((const __m128i *)(a4 + 8));
*(_WORD *)(v10 + 4) = func0(1000);
}
*(_WORD *)(v10 + 2) = in_cusm(v10, 28LL);
v34 = 0LL;
v29[0] = v10;
v29[1] = v17;
*(_QWORD *)&addr[0].msg_namelen = 28LL;
*(_QWORD *)&addr[0].msg_flags = 0LL;
addr[0].msg_name = a3;
addr[0].msg_iov = (struct iovec *)v29;
addr[0].msg_iovlen = 1LL;
addr[0].msg_control = &v30;
addr[0].msg_controllen = 40LL;
v31 = 41;
v32 = 50;
v30 = 36LL;
v34 = *(unsigned int *)(a1 + 212);
v33 = _mm_loadu_si128((const __m128i *)(a1 + 88));
if ( sendmsg(fd, addr, 0) < 0 )
{
v18 = _errno_location();
v19 = strerror(*v18);
logger_build(1LL, "ERROR", "send_igmp_mld_query", 248LL, "mld query: sendmsg failed: %s\n", v19);
}
goto LABEL_10;
}
if ( !a5 )
{
v17 = 28;
goto LABEL_28;
}
v20 = v27 - 48 - 16LL;
if ( v20 <= 0x1B )
{
v17 = 28;
goto LABEL_28;
}
v17 = 28;
while ( 1 )
{
if ( *((_WORD *)a5 + 8) == 10 )
{
if ( !(unsigned int)imp_source_is_scheduled(a5, a6) )
{
a5 = (__int64 *)*a5;
goto LABEL_37;
}
v21 = *(_WORD *)(v10 + 26);
*(__m128i *)(16LL * v21 + v10 + 28) = _mm_loadu_si128((const __m128i *)(a5 + 3));
*(_WORD *)(v10 + 26) = v21 + 1;
v17 += 16;
}
a5 = (__int64 *)*a5;
LABEL_37:
if ( !a5 || v17 > v20 )
goto LABEL_28;
}
}
LABEL_10:
free((void *)v10);
}

original_code:
void send_igmp_mld_query(imp_interface *p_if, im_version version,
    pi_addr *p_dst, pi_addr *p_gp_addr, imp_source* p_sources, int sflag)
{
    int family = 0;
    char *p = ((void *)0);
    int max_len = 0;
    if(p_if == ((void *)0)) {
        logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 71, "p_if is NULL\n");
        return;
    }
    family = p_if->if_addr.ss.ss_family;
    if(family != p_dst->ss.ss_family || (p_gp_addr != ((void *)0) &&
        family != p_gp_addr->ss.ss_family)) {
        logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 80, "family don't match, can't send igmp query\n");
        return;
    }
    max_len = p_if->if_mtu;
    if((p = malloc(max_len)) == ((void *)0)){
       logger_build(LOG_PRI_FATAL, "FATAL", __FUNCTION__, 87, "malloc failed\n");
       exit(1);
    }
    bzero(p, max_len);
    if(family == 2) {
        struct igmpv3_query* p_igh;
        struct sockaddr_in din;
        int igh_len = 0;
        int socket = get_igmp_mld_socket(2);
        bzero(&din, sizeof(struct sockaddr_in));
        logger_build(LOG_PRI_DEBUG, "DEBUG", __FUNCTION__, 101, "src = %s dst = %s \n", imp_pi_ntoa(&p_if->if_addr), imp_pi_ntoa(p_dst));
        max_len -= (sizeof(struct iphdr) + 4);
        logger_build(LOG_PRI_DEBUG, "DEBUG", __FUNCTION__, 104, "max_len = %d\n", max_len);
        p_igh = (struct igmpv3_query*)p;
        p_igh->type = 0x11;
        if(version != IM_IGMPv1)
            p_igh->code = 10 * 10; ;
        if (p_gp_addr != ((void *)0)) {
            logger_build(LOG_PRI_DEBUG, "DEBUG", __FUNCTION__, 115, "g = %s \n", imp_pi_ntoa(p_gp_addr));
            p_igh->group = p_gp_addr->v4.sin_addr.s_addr;
            p_igh->code = 1 * 10;
        }
        p_igh->csum = 0;
        p_igh->qrv = 2;
        p_igh->qqic = 125;
        p_igh->nsrcs = 0;
        p_igh->suppress = sflag;
        while(p_sources && version == IM_IGMPv3_MLDv2) {
            if(igh_len > max_len - sizeof(struct in_addr))
                break;
            if(p_sources->src_addr.ss.ss_family == 2) {
                if(imp_source_is_scheduled(p_sources, sflag) == 0) {
                    p_sources = ((p_sources)->link.le_next);
                    continue;
                }
                p_igh->srcs[p_igh->nsrcs] = p_sources->src_addr.v4.sin_addr.s_addr;
                p_igh->nsrcs++;
                igh_len += sizeof(int);
            }
            p_sources = ((p_sources)->link.le_next);
        }
        if(version == IM_IGMPv3_MLDv2)
            igh_len = sizeof(struct igmpv3_query) + p_igh->nsrcs * sizeof(int);
        else
            igh_len = sizeof(struct igmphdr);
        logger_build(LOG_PRI_DEBUG, "DEBUG", __FUNCTION__, 155, "igh_len  = %d\n", igh_len);
        p_igh->csum = in_cusm((unsigned short*)p_igh, igh_len);
        setsockopt(socket, IPPROTO_IP, 32,
            &p_if->if_addr.v4.sin_addr, sizeof(struct in_addr));
        din.sin_family = 2;
        din.sin_addr.s_addr = p_dst->v4.sin_addr.s_addr;
        if(sendto(socket, p_igh, igh_len, 0, (struct sockaddr*)&din, sizeof(din)) == -1){
            logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 165, "sendto failed\n");
        }
    }else if(family== 10) {
        struct imp_mldv2_query_hdr *p_hdr;
        int p_hdr_len;
        int socket = get_igmp_mld_socket(10);
        max_len -= (sizeof(struct ip6_hdr) + 8);
        p_hdr = (struct imp_mldv2_query_hdr *)p;
        p_hdr->mldh.mld_icmp6_hdr.icmp6_type = 130;
        p_hdr->mldh.mld_icmp6_hdr.icmp6_code = 0;
        p_hdr->mldh.mld_icmp6_hdr.icmp6_cksum = 0;
        p_hdr->mldh.mld_icmp6_hdr.icmp6_dataun.icmp6_un_data16[0] = htons(10000);
        p_hdr->suppress = sflag;
        p_hdr->qrv = 2;
        p_hdr->qqic = 125;
        p_hdr->nsrcs = 0;
        if (version == IM_IGMPv3_MLDv2)
            p_hdr_len = sizeof(struct imp_mldv2_query_hdr);
        else
            p_hdr_len = sizeof(struct mld_hdr);
        while(p_sources && version == IM_IGMPv3_MLDv2) {
            if(p_hdr_len > max_len - sizeof(struct in6_addr))
                break;
            if(p_sources->src_addr.ss.ss_family == 10) {
                if(imp_source_is_scheduled(p_sources, sflag) == 0) {
                    p_sources = ((p_sources)->link.le_next);
                    continue;
                }
                memcpy(&p_hdr->srcs[p_hdr->nsrcs],
                    &p_sources->src_addr.v6.sin6_addr, sizeof(struct in6_addr));
                p_hdr->nsrcs++;
                p_hdr_len += sizeof(struct in6_addr);
            }
            p_sources = ((p_sources)->link.le_next);
       }
       if (p_gp_addr != ((void *)0)) {
            memcpy(&p_hdr->mldh.mld_addr, &p_gp_addr->v6.sin6_addr,
                sizeof(struct in6_addr));
            p_hdr->mldh.mld_icmp6_hdr.icmp6_dataun.icmp6_un_data16[0] = htons(1000);
        }
        p_hdr->mldh.mld_icmp6_hdr.icmp6_cksum = in_cusm((unsigned short*)p_hdr,
            sizeof(struct imp_mldv2_query_hdr));
        unsigned char cbuf[((((sizeof(struct in6_pktinfo)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)))] = {0};
        struct iovec iov = {
            p_hdr,
            p_hdr_len
        };
        struct msghdr msg = {
            .msg_name = (void *)&p_dst->v6,
            .msg_namelen = sizeof(p_dst->v6),
            .msg_iov = &iov,
            .msg_iovlen = 1,
            .msg_control = cbuf,
            .msg_controllen = sizeof(cbuf)
        };
        struct cmsghdr *cmsg = ((size_t) (&msg)->msg_controllen >= sizeof (struct cmsghdr) ? (struct cmsghdr *) (&msg)->msg_control : (struct cmsghdr *) 0);
        cmsg->cmsg_level = IPPROTO_IPV6;
        cmsg->cmsg_type = 50;
        cmsg->cmsg_len = ((((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)) + (sizeof(struct in6_pktinfo)));
        struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)((cmsg)->__cmsg_data);
        pktinfo->ipi6_ifindex = p_if->if_index;
        memcpy(&pktinfo->ipi6_addr, &p_if->if_addr.v6.sin6_addr, sizeof(struct in6_addr));
        if (sendmsg(socket, &msg, 0) < 0) {
            logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 248, "mld query: sendmsg failed: %s\n", strerror((*__errno_location ())));
        }
    }
    free(p);
    return;
}

canonical_original_code:
void send_igmp_mld_query(struct imp_interface *p_if, enum im_version version, union _pi_addr *p_dst, union _pi_addr *p_gp_addr, struct imp_source *p_sources, int sflag)
{
    int family = 0;
    char *p = ((void *)0);
    int max_len = 0;
    if(p_if == ((void *)0)) {
        logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 71, "p_if is NULL\n");
        return;
    }
    family = p_if->if_addr.ss.ss_family;
    if(family != p_dst->ss.ss_family || (p_gp_addr != ((void *)0) &&
        family != p_gp_addr->ss.ss_family)) {
        logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 80, "family don't match, can't send igmp query\n");
        return;
    }
    max_len = p_if->if_mtu;
    if((p = malloc(max_len)) == ((void *)0)){
       logger_build(LOG_PRI_FATAL, "FATAL", __FUNCTION__, 87, "malloc failed\n");
       exit(1);
    }
    bzero(p, max_len);
    if(family == 2) {
        struct igmpv3_query *p_igh;
        struct sockaddr_in din;
        int igh_len = 0;
        int socket = get_igmp_mld_socket(2);
        bzero(&din, sizeof(struct sockaddr_in));
        logger_build(LOG_PRI_DEBUG, "DEBUG", __FUNCTION__, 101, "src = %s dst = %s \n", imp_pi_ntoa(&p_if->if_addr), imp_pi_ntoa(p_dst));
        max_len -= (sizeof(struct iphdr) + 4);
        logger_build(LOG_PRI_DEBUG, "DEBUG", __FUNCTION__, 104, "max_len = %d\n", max_len);
        p_igh = (struct igmpv3_query *)p;
        p_igh->type = 0x11;
        if(version != IM_IGMPv1)
            p_igh->code = 10 * 10; ;
        if (p_gp_addr != ((void *)0)) {
            logger_build(LOG_PRI_DEBUG, "DEBUG", __FUNCTION__, 115, "g = %s \n", imp_pi_ntoa(p_gp_addr));
            p_igh->group = p_gp_addr->v4.sin_addr.s_addr;
            p_igh->code = 1 * 10;
        }
        p_igh->csum = 0;
        p_igh->qrv = 2;
        p_igh->qqic = 125;
        p_igh->nsrcs = 0;
        p_igh->suppress = sflag;
        while(p_sources && version == IM_IGMPv3_MLDv2) {
            if(igh_len > max_len - sizeof(struct in_addr))
                break;
            if(p_sources->src_addr.ss.ss_family == 2) {
                if(imp_source_is_scheduled(p_sources, sflag) == 0) {
                    p_sources = ((p_sources)->link.le_next);
                    continue;
                }
                p_igh->srcs[p_igh->nsrcs] = p_sources->src_addr.v4.sin_addr.s_addr;
                p_igh->nsrcs++;
                igh_len += sizeof(int);
            }
            p_sources = ((p_sources)->link.le_next);
        }
        if(version == IM_IGMPv3_MLDv2)
            igh_len = sizeof(struct igmpv3_query) + p_igh->nsrcs * sizeof(int);
        else
            igh_len = sizeof(struct igmphdr);
        logger_build(LOG_PRI_DEBUG, "DEBUG", __FUNCTION__, 155, "igh_len  = %d\n", igh_len);
        p_igh->csum = in_cusm((unsigned short *)p_igh, igh_len);
        setsockopt(socket, IPPROTO_IP, 32,
            &p_if->if_addr.v4.sin_addr, sizeof(struct in_addr));
        din.sin_family = 2;
        din.sin_addr.s_addr = p_dst->v4.sin_addr.s_addr;
        if(sendto(socket, p_igh, igh_len, 0, (struct sockaddr *)&din, sizeof(din)) == -1){
            logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 165, "sendto failed\n");
        }
    }else if(family== 10) {
        struct imp_mldv2_query_hdr *p_hdr;
        int p_hdr_len;
        int socket = get_igmp_mld_socket(10);
        max_len -= (sizeof(struct ip6_hdr) + 8);
        p_hdr = (struct imp_mldv2_query_hdr *)p;
        p_hdr->mldh.mld_icmp6_hdr.icmp6_type = 130;
        p_hdr->mldh.mld_icmp6_hdr.icmp6_code = 0;
        p_hdr->mldh.mld_icmp6_hdr.icmp6_cksum = 0;
        p_hdr->mldh.mld_icmp6_hdr.icmp6_dataun.icmp6_un_data16[0] = htons(10000);
        p_hdr->suppress = sflag;
        p_hdr->qrv = 2;
        p_hdr->qqic = 125;
        p_hdr->nsrcs = 0;
        if (version == IM_IGMPv3_MLDv2)
            p_hdr_len = sizeof(struct imp_mldv2_query_hdr);
        else
            p_hdr_len = sizeof(struct mld_hdr);
        while(p_sources && version == IM_IGMPv3_MLDv2) {
            if(p_hdr_len > max_len - sizeof(struct in6_addr))
                break;
            if(p_sources->src_addr.ss.ss_family == 10) {
                if(imp_source_is_scheduled(p_sources, sflag) == 0) {
                    p_sources = ((p_sources)->link.le_next);
                    continue;
                }
                memcpy(&p_hdr->srcs[p_hdr->nsrcs],
                    &p_sources->src_addr.v6.sin6_addr, sizeof(struct in6_addr));
                p_hdr->nsrcs++;
                p_hdr_len += sizeof(struct in6_addr);
            }
            p_sources = ((p_sources)->link.le_next);
       }
       if (p_gp_addr != ((void *)0)) {
            memcpy(&p_hdr->mldh.mld_addr, &p_gp_addr->v6.sin6_addr,
                sizeof(struct in6_addr));
            p_hdr->mldh.mld_icmp6_hdr.icmp6_dataun.icmp6_un_data16[0] = htons(1000);
        }
        p_hdr->mldh.mld_icmp6_hdr.icmp6_cksum = in_cusm((unsigned short *)p_hdr,
            sizeof(struct imp_mldv2_query_hdr));
        unsigned char cbuf[-1] = {0};
        struct iovec iov = {
            p_hdr,
            p_hdr_len
        };
        struct msghdr msg = {
            .msg_name = (void *)&p_dst->v6,
            .msg_namelen = sizeof(p_dst->v6),
            .msg_iov = &iov,
            .msg_iovlen = 1,
            .msg_control = cbuf,
            .msg_controllen = sizeof(cbuf)
        };
        struct cmsghdr *cmsg = ((size_t) (&msg)->msg_controllen >= sizeof (struct cmsghdr) ? (struct cmsghdr *) (&msg)->msg_control : (struct cmsghdr *) 0);
        cmsg->cmsg_level = IPPROTO_IPV6;
        cmsg->cmsg_type = 50;
        cmsg->cmsg_len = ((((sizeof (struct cmsghdr)) + sizeof (unsigned long) - 1) & (unsigned long) ~(sizeof (unsigned long) - 1)) + (sizeof(struct in6_pktinfo)));
        struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)((cmsg)->__cmsg_data);
        pktinfo->ipi6_ifindex = p_if->if_index;
        memcpy(&pktinfo->ipi6_addr, &p_if->if_addr.v6.sin6_addr, sizeof(struct in6_addr));
        if (sendmsg(socket, &msg, 0) < 0) {
            logger_build(LOG_PRI_ERROR, "ERROR", __FUNCTION__, 248, "mld query: sendmsg failed: %s\n", strerror((*__errno_location ())));
        }
    }
    free(p);
    return;
}

variable_types: struct imp_interface { struct { struct imp_interface *le_next; struct imp_interface **le_prev; } link; char if_name[64]; union _pi_addr { struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; } v4; struct sockaddr_in6 { unsigned short sin6_family; unsigned short sin6_port; unsigned int sin6_flowinfo; struct in6_addr { union { unsigned char __u6_addr8[16]; unsigned short __u6_addr16[8]; unsigned int __u6_addr32[4]; } __in6_u; } sin6_addr; unsigned int sin6_scope_id; } v6; struct sockaddr { unsigned short sa_family; char sa_data[14]; } sa; struct sockaddr_storage { unsigned short ss_family; char __ss_padding[-1]; unsigned long __ss_align; } ss; } if_addr; enum if_type { INTERFACE_DOWNSTREAM=0, INTERFACE_UPSTREAM=1 } type; int if_index; int if_igmp_socket; int if_mld_socket; int if_mtu; int startup; struct { struct imp_group { struct { struct imp_group *le_next; struct imp_group **le_prev; } link; int if_index; struct imp_interface *parent_if; union _pi_addr group_addr; enum group_type { GROUP_EXCLUDE=0, GROUP_INCLUDE=1, GROUP_UNDEFINED=2 } type; enum im_version { IM_DISABLE=0, IM_IGMPv1=1, IM_IGMPv2_MLDv1=2, IM_IGMPv3_MLDv2=3 } version; struct imp_timer { struct { struct imp_timer *le_next; struct imp_timer **le_prev; } link; struct timeval { long tv_sec; long tv_usec; } tm; struct imp_timer *(*expire)(void *); void *expire_data; } *timer; struct imp_timer *v1_timer; struct imp_timer *v2_timer; struct imp_timer *sch_timer; int gs_sch_times; struct { struct imp_source { struct { struct imp_source *le_next; struct imp_source **le_prev; } link; union _pi_addr src_addr; struct imp_timer *timer; struct imp_group *parent_gp; int times; } *lh_first; } src_list; } *lh_first; } group_list; struct imp_timer *gq_timer; } *

variable_types: sflag int

variable_types: family int

variable_types:
p
char *

variable_types: struct igmpv3_query { unsigned char type; unsigned char code; unsigned short csum; unsigned int group; unsigned char qrv; unsigned char qqic; unsigned short nsrcs; unsigned int srcs[]; } *

variable_types: socket int

variable_types: struct imp_mldv2_query_hdr { struct mld_hdr { struct icmp6_hdr { unsigned char icmp6_type; unsigned char icmp6_code; unsigned short icmp6_cksum; union { unsigned int icmp6_un_data32[1]; unsigned short icmp6_un_data16[2]; unsigned char icmp6_un_data8[4]; } icmp6_dataun; } mld_icmp6_hdr; struct in6_addr { union { unsigned char __u6_addr8[16]; unsigned short __u6_addr16[8]; unsigned int __u6_addr32[4]; } __in6_u; } mld_addr; } mldh; unsigned char qrv; unsigned char qqic; unsigned short nsrcs; struct in6_addr srcs[]; } *

variable_types:
cbuf
unsigned char [-1]

variable_types: struct msghdr { void *msg_name; unsigned int msg_namelen; struct iovec { void *iov_base; unsigned long iov_len; } *msg_iov; unsigned long msg_iovlen; void *msg_control; unsigned long msg_controllen; int msg_flags; }

variable_types: struct cmsghdr { unsigned long cmsg_len; int cmsg_level; int cmsg_type; unsigned char __cmsg_data[]; } *

variable_types: struct in6_pktinfo { struct in6_addr { union { unsigned char __u6_addr8[16]; unsigned short __u6_addr16[8]; unsigned int __u6_addr32[4]; } __in6_u; } ipi6_addr; unsigned int ipi6_ifindex; } *

user_defined_types: struct msghdr { void *msg_name; unsigned int msg_namelen; struct iovec *msg_iov; unsigned long msg_iovlen; void *msg_control; unsigned long msg_controllen; int msg_flags; }

user_defined_types: struct iphdr { unsigned int ihl; unsigned int version; unsigned char tos; unsigned short tot_len; unsigned short id; unsigned short frag_off; unsigned char ttl; unsigned char protocol; unsigned short check; unsigned int saddr; unsigned int daddr; }

user_defined_types: struct igmphdr { unsigned char type; unsigned char code; unsigned short csum; unsigned int group; }

user_defined_types: struct ip6_hdr { union { struct ip6_hdrctl ip6_un1; unsigned char ip6_un2_vfc; } ip6_ctlun; struct in6_addr ip6_src; struct in6_addr ip6_dst; }

user_defined_types: struct imp_mldv2_query_hdr { struct mld_hdr mldh; unsigned char qrv; unsigned char qqic; unsigned short nsrcs; struct in6_addr srcs[]; }

user_defined_types: struct mld_hdr { struct icmp6_hdr mld_icmp6_hdr; struct in6_addr mld_addr; }

user_defined_types: struct in6_pktinfo { struct in6_addr ipi6_addr; unsigned int ipi6_ifindex; }

user_defined_types: struct imp_interface { struct { struct imp_interface *le_next; struct imp_interface **le_prev; } link; char if_name[64]; union _pi_addr if_addr; enum if_type type; int if_index; int if_igmp_socket; int if_mld_socket; int if_mtu; int startup; struct { struct imp_group *lh_first; } group_list; struct imp_timer *gq_timer; }

user_defined_types: union _pi_addr { struct sockaddr_in v4; struct sockaddr_in6 v6; struct sockaddr sa; struct sockaddr_storage ss; }

user_defined_types: struct ip6_hdrctl { unsigned int ip6_un1_flow; unsigned short ip6_un1_plen; unsigned char ip6_un1_nxt; unsigned char ip6_un1_hlim; }

user_defined_types: struct sockaddr_in6 { unsigned short sin6_family; unsigned short sin6_port; unsigned int sin6_flowinfo; struct in6_addr sin6_addr; unsigned int sin6_scope_id; }

user_defined_types: struct imp_group { struct { struct imp_group *le_next; struct imp_group **le_prev; } link; int if_index; struct imp_interface *parent_if; union _pi_addr group_addr; enum group_type type; enum im_version version; struct imp_timer *timer; struct imp_timer *v1_timer; struct imp_timer *v2_timer; struct imp_timer *sch_timer; int gs_sch_times; struct { struct imp_source *lh_first; } src_list; }


decompiled_code:
unsigned __int64 init_point_list()
{
unsigned __int64 result; // rax

*(&p_pool + 351) = 0LL;
*((_DWORD *)&p_pool + 600) = 0;
result = (unsigned int)((_DWORD)&p_pool + 2404);
do
{
*(_DWORD *)result = 0;
result += 4LL;
}
while ( result != (_DWORD)&p_pool + 2804 );
return result;
}

canonical_decompiled_code:
unsigned __int64 func0()
{
unsigned __int64 result; // rax

*(&p_pool + 351) = 0LL;
*((_DWORD *)&p_pool + 600) = 0;
result = (unsigned int)((_DWORD)&p_pool + 2404);
do
{
*(_DWORD *)result = 0;
result += 4LL;
}
while ( result != (_DWORD)&p_pool + 2804 );
return result;
}

original_code:
void init_point_list(){
    p_pool.head = ((void *)0);
    p_pool.points_count = 0;
    int i;
    for(i=0; i<100; i++){
        p_pool.ipoint[i] = 0;
    }
}

variable_types: i int


decompiled_code:
__int64 find_free_pos()
{
__int64 v0; // rax
unsigned int v1; // edx

v0 = 99LL;
while ( 1 )
{
v1 = v0;
if ( !*((_DWORD *)&p_pool + v0 + 601) )
break;
if ( --v0 == -1 )
return (unsigned int)-1;
}
return v1;
}

canonical_decompiled_code:
__int64 func1()
{
__int64 v0; // rax
unsigned int v1; // edx

v0 = 99LL;
while ( 1 )
{
v1 = v0;
if ( !*((_DWORD *)&p_pool + v0 + 601) )
break;
if ( --v0 == -1 )
return (unsigned int)-1;
}
return v1;
}

original_code:
int find_free_pos(){
    int i=100 -1;
    while(i>=0){
        if(p_pool.ipoint[i] == 0){
            return i;
        }
        --i;
    }
    return -1;
}

canonical_original_code:
int find_free_pos(){
    int i = 100 -1;
    while(i>=0){
        if(p_pool.ipoint[i] == 0){
            return i;
        }
        --i;
    }
    return -1;
}


decompiled_code:
_BOOL8 is_pp_empty()
{
return *((_DWORD *)&p_pool + 600) == 0;
}

canonical_decompiled_code:
_BOOL8 func2()
{
return *((_DWORD *)&p_pool + 600) == 0;
}

original_code:
BOOL is_pp_empty(){
    if(p_pool.points_count == 0){
        return 1;
    }else{
        return 0;
    }
}

canonical_original_code:
int is_pp_empty(){
    if(p_pool.points_count == 0){
        return 1;
    }else{
        return 0;
    }
}


decompiled_code:
__int64 top_point()
{
return *(_QWORD *)p_pool[351];
}

canonical_decompiled_code:
__int64 func4()
{
return *(_QWORD *)p_pool[351];
}

original_code:
struct point top_point(){
     return p_pool.head->p;
 }

return_type: struct point { int x; int y; }


original_code:
struct point pop_point(){
    struct point p_rst;
    p_rst.x = p_pool.head->p.x;
    p_rst.y = p_pool.head->p.y;
    p_pool.points_count--;
    int freenode = p_pool.head->pos;
    p_pool.ipoint[freenode] = 0;
    p_pool.head = p_pool.head->next;
    return p_rst;
}

variable_types: freenode int


decompiled_code:
int __fastcall print_point(unsigned int *a1)
{
return printf("%d %d \n", *a1, a1[1]);
}

canonical_decompiled_code:
int __fastcall func6(unsigned int *a1)
{
return printf("%d %d \n", *a1, a1[1]);
}

original_code:
void print_point(struct point* p){
    printf("%d %d \n", p->x, p->y);
}

canonical_original_code:
void print_point(struct point *p){
    printf("%d %d \n", p->x, p->y);
}

variable_types:
p
struct point { int x; int y; } *


decompiled_code:
void __fastcall p_quicksort(int *a1, int *a2)
{
int *v2; // r12

if ( a1 != a2 )
{
v2 = get_partion(a1, a2);
p_quicksort(a1, v2);
p_quicksort(*((_QWORD *)v2 + 2), a2);
}
}

original_code:
void p_quicksort(struct point_node *p_begin, struct point_node *p_end){
    if(p_begin != p_end){
        struct point_node *partion = get_partion(p_begin, p_end);
        p_quicksort(p_begin, partion);
        p_quicksort(partion->next, p_end);
    }
}

variable_types: struct point_node { struct point { int x; int y; } p; int pos; struct point_node *next; } *

user_defined_types: struct point_node { struct point p; int pos; struct point_node *next; }


decompiled_code:
void points_quicksort()
{
p_quicksort((int *)p_pool[351], *(int **)(p_pool[352] + 16));
}

original_code:
void points_quicksort(){
    p_quicksort(p_pool.head, p_pool.tail->next);
}


min

decompiled_code:
__int64 __fastcall min(unsigned int a1, unsigned int a2)
{
__int64 result; // rax

result = a2;
if ( (int)a1 <= (int)a2 )
result = a1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1, unsigned int a2)
{
__int64 result; // rax

result = a2;
if ( (int)a1 <= (int)a2 )
result = a1;
return result;
}

original_code:
int min(int x, int y){
    if(x <= y){
        return x;
    }else{
        return y;
    }
}

variable_types: x int

variable_types: y int


max

decompiled_code:
__int64 __fastcall max(unsigned int a1, unsigned int a2)
{
__int64 result; // rax

result = a2;
if ( (int)a1 >= (int)a2 )
result = a1;
return result;
}

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

result = a2;
if ( (int)a1 >= (int)a2 )
result = a1;
return result;
}

original_code:
int max(int x, int y){
    if(x >= y){
        return x;
    }else{
        return y;
    }
}


decompiled_code:
double __fastcall cross_product(__int64 a1, __int64 a2, __int64 a3)
{
return (double)((HIDWORD(a2) - HIDWORD(a3)) * ((int)a1 - (int)a3) - (HIDWORD(a1) - HIDWORD(a3)) * ((int)a2 - (int)a3));
}

canonical_decompiled_code:
double __fastcall func2(__int64 a1, __int64 a2, __int64 a3)
{
return (double)((HIDWORD(a2) - HIDWORD(a3)) * ((int)a1 - (int)a3) - (HIDWORD(a1) - HIDWORD(a3)) * ((int)a2 - (int)a3));
}

original_code:
double cross_product(point_t p1, point_t p2, point_t p0){
    return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x - p0.x)*(p1.y - p0.y);
}

canonical_original_code:
double cross_product(struct point p1, struct point p2, struct point p0){
    return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x - p0.x)*(p1.y - p0.y);
}


direction

decompiled_code:
double __fastcall direction(__int64 a1, __int64 a2, __int64 a3)
{
return cross_product(a3, a2, a1);
}

canonical_decompiled_code:
double __fastcall func3(__int64 a1, __int64 a2, __int64 a3)
{
return func2(a3, a2, a1);
}

original_code:
double direction(point_t pi, point_t pj, point_t pk){
    return cross_product(pk, pj, pi);
}

canonical_original_code:
double direction(struct point pi, struct point pj, struct point pk){
    return cross_product(pk, pj, pi);
}

variable_types:
pi
struct point { int x; int y; }

variable_types:
pj
struct point

variable_types:
pk
struct point


decompiled_code:
__int64 __fastcall on_segment(__int64 a1, __int64 a2, __int64 a3)
{
int v3; // ebx
__int64 v4; // r13
int v5; // ebp
int v6; // er12
int v7; // eax
int v8; // edx
int v9; // ecx
int v10; // eax
int v12; // [rsp+4h] [rbp-34h]

v3 = a3;
v4 = a3 >> 32;
v12 = min(a1, a2);
v5 = max(a1, a2);
v6 = min(HIDWORD(a1), HIDWORD(a2));
v7 = max(HIDWORD(a1), HIDWORD(a2));
v8 = v7;
LOBYTE(v7) = v3 <= v5;
LOBYTE(v9) = v12 <= v3;
v10 = v9 & v7;
LOBYTE(v9) = (int)v4 >= v6;
return (v8 >= (int)v4) & v9 & (unsigned int)v10;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, __int64 a2, __int64 a3)
{
int v3; // ebx
__int64 v4; // r13
int v5; // ebp
int v6; // er12
int v7; // eax
int v8; // edx
int v9; // ecx
int v10; // eax
int v12; // [rsp+4h] [rbp-34h]

v3 = a3;
v4 = a3 >> 32;
v12 = func0(a1, a2);
v5 = func1(a1, a2);
v6 = func0(HIDWORD(a1), HIDWORD(a2));
v7 = func1(HIDWORD(a1), HIDWORD(a2));
v8 = v7;
LOBYTE(v7) = v3 <= v5;
LOBYTE(v9) = v12 <= v3;
v10 = v9 & v7;
LOBYTE(v9) = (int)v4 >= v6;
return (v8 >= (int)v4) & v9 & (unsigned int)v10;
}

original_code:
BOOL on_segment(point_t pi, point_t pj, point_t pk){
    int minx = min(pi.x, pj.x);
    int maxx = max(pi.x, pj.x);
    int miny = min(pi.y, pj.y);
    int maxy = max(pi.y, pj.y);
    if(pk.x >= minx && pk.x<=maxx && pk.y >= miny && pk.y <= maxy){
        return 1;
    }else{
        return 0;
    }
}

canonical_original_code:
int on_segment(struct point pi, struct point pj, struct point pk){
    int minx = min(pi.x, pj.x);
    int maxx = max(pi.x, pj.x);
    int miny = min(pi.y, pj.y);
    int maxy = max(pi.y, pj.y);
    if(pk.x >= minx && pk.x<=maxx && pk.y >= miny && pk.y <= maxy){
        return 1;
    }else{
        return 0;
    }
}

variable_types: minx int

variable_types: maxx int

variable_types: miny int

variable_types: maxy int


decompiled_code:
__int64 __fastcall seg_intersection(__int64 a1, __int64 a2, __int64 a3, __int64 a4, _DWORD *a5)
{
double v5; // xmm2_8
__int64 result; // rax

v5 = (double)((HIDWORD(a3) - HIDWORD(a4)) * ((int)a1 - (int)a3) - ((int)a3 - (int)a4) * (HIDWORD(a1) - HIDWORD(a3)))
/ (double)((HIDWORD(a3) - HIDWORD(a4)) * ((int)a1 - (int)a2) - ((int)a3 - (int)a4) * (HIDWORD(a1) - HIDWORD(a2)));
*a5 = (int)((double)((int)a2 - (int)a1) * v5 + (double)(int)a1);
result = (unsigned int)(int)((double)(HIDWORD(a2) - HIDWORD(a1)) * v5 + (double)SHIDWORD(a1));
a5[1] = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2, __int64 a3, __int64 a4, _DWORD *a5)
{
double v5; // xmm2_8
__int64 result; // rax

v5 = (double)((HIDWORD(a3) - HIDWORD(a4)) * ((int)a1 - (int)a3) - ((int)a3 - (int)a4) * (HIDWORD(a1) - HIDWORD(a3)))
/ (double)((HIDWORD(a3) - HIDWORD(a4)) * ((int)a1 - (int)a2) - ((int)a3 - (int)a4) * (HIDWORD(a1) - HIDWORD(a2)));
*a5 = (int)((double)((int)a2 - (int)a1) * v5 + (double)(int)a1);
result = (unsigned int)(int)((double)(HIDWORD(a2) - HIDWORD(a1)) * v5 + (double)SHIDWORD(a1));
a5[1] = result;
return result;
}

original_code:
void seg_intersection(point_t u1, point_t u2, point_t v1, point_t v2, point_t *rst){
    *rst = u1;
    double t=(double)((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
        /(double)((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
    rst->x = rst->x + ((u2.x-u1.x)*t);
    rst->y = rst->y + ((u2.y-u1.y)*t);
}

canonical_original_code:
void seg_intersection(struct point u1, struct point u2, struct point v1, struct point v2, struct point *rst){
    *rst = u1;
    double t = (double)((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
        /(double)((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
    rst->x = rst->x + ((u2.x-u1.x)*t);
    rst->y = rst->y + ((u2.y-u1.y)*t);
}

variable_types:
rst
struct point *

variable_types: t double


decompiled_code:
__int64 __fastcall get_seg_intersection(__int64 a1, __int64 a2, __int64 a3, __int64 a4, _DWORD *a5)
{
double v8; // r15
__int64 result; // rax
double v10; // [rsp+0h] [rbp-48h]
double v11; // [rsp+8h] [rbp-40h]
double v12; // [rsp+10h] [rbp-38h]

v10 = direction(a3, a4, a1);
v11 = direction(a3, a4, a2);
v8 = direction(a1, a2, a3);
v12 = direction(a1, a2, a4);
if ( v10 * v11 < 0.0 && v8 * v12 < 0.0
|| v10 == 0.0 && (unsigned int)on_segment(a3, a4, a1)
|| v11 == 0.0 && (unsigned int)on_segment(a3, a4, a2)
|| v8 == 0.0 && (unsigned int)on_segment(a1, a2, a3) )
{
LABEL_10:
seg_intersection(a1, a2, a3, a4, a5);
return 1LL;
}
if ( v12 == 0.0 )
{
result = on_segment(a1, a2, a4);
if ( !(_DWORD)result )
return result;
goto LABEL_10;
}
return 0LL;
}

original_code:
BOOL get_seg_intersection(point_t p1, point_t p2, point_t p3, point_t p4, point_t *rst){
    double d1 = direction(p3, p4, p1);
    double d2 = direction(p3, p4, p2);
    double d3 = direction(p1, p2, p3);
    double d4 = direction(p1, p2, p4);
    if(d1*d2 < 0 && d3*d4 < 0){
        seg_intersection(p1, p2, p3, p4, rst);
        return 1;
    }else if(d1 == 0 && on_segment(p3, p4, p1)){
        seg_intersection(p1, p2, p3, p4, rst);
        return 1;
    }else if(d2 == 0 && on_segment(p3, p4, p2)){
        seg_intersection(p1, p2, p3, p4, rst);
        return 1;
    }else if(d3 == 0 && on_segment(p1, p2, p3)){
        seg_intersection(p1, p2, p3, p4, rst);
        return 1;
    }else if(d4 == 0 && on_segment(p1, p2, p4)){
        seg_intersection(p1, p2, p3, p4, rst);
        return 1;
    }
    return 0;
}

canonical_original_code:
int get_seg_intersection(struct point p1, struct point p2, struct point p3, struct point p4, struct point *rst){
    double d1 = direction(p3, p4, p1);
    double d2 = direction(p3, p4, p2);
    double d3 = direction(p1, p2, p3);
    double d4 = direction(p1, p2, p4);
    if(d1*d2 < 0 && d3*d4 < 0){
        seg_intersection(p1, p2, p3, p4, rst);
        return 1;
    }else if(d1 == 0 && on_segment(p3, p4, p1)){
        seg_intersection(p1, p2, p3, p4, rst);
        return 1;
    }else if(d2 == 0 && on_segment(p3, p4, p2)){
        seg_intersection(p1, p2, p3, p4, rst);
        return 1;
    }else if(d3 == 0 && on_segment(p1, p2, p3)){
        seg_intersection(p1, p2, p3, p4, rst);
        return 1;
    }else if(d4 == 0 && on_segment(p1, p2, p4)){
        seg_intersection(p1, p2, p3, p4, rst);
        return 1;
    }
    return 0;
}


decompiled_code:
unsigned __int64 init_arc_pool()
{
unsigned __int64 result; // rax

*(&arc_pool + 751) = 0LL;
*((_DWORD *)&arc_pool + 1500) = 0;
result = (unsigned int)((_DWORD)&arc_pool + 5600);
do
{
*(_DWORD *)result = 0;
result += 4LL;
}
while ( result != (_DWORD)&arc_pool + 6000 );
return result;
}

canonical_decompiled_code:
unsigned __int64 func0()
{
unsigned __int64 result; // rax

*(&arc_pool + 751) = 0LL;
*((_DWORD *)&arc_pool + 1500) = 0;
result = (unsigned int)((_DWORD)&arc_pool + 5600);
do
{
*(_DWORD *)result = 0;
result += 4LL;
}
while ( result != (_DWORD)&arc_pool + 6000 );
return result;
}

original_code:
void init_arc_pool(){
    arc_pool.head = ((void *)0);
    arc_pool.count = 0;
    int i;
    for(i=0; i<100; i++){
        arc_pool.iarc[i] = 0;
    }
}