initPinnedMap

decompiled_code:
__int64 initPinnedMap()
{
__int64 result; // rax

pinnedMap[0] = 0xFFFFFFB0FFFFFE70LL;
pinnedMap[1] = 0xFFFFFFD8FFFFFFB0LL;
pinnedMap[2] = 0xFFFFFFD8FFFFFFD8LL;
pinnedMap[3] = 0xFFFFFFCEFFFFFFCELL;
*(__int64 *)((char *)&pinnedMap[4] + 4) = 0xFFFFFFE2FFFFFFE2LL;
*(__int64 *)((char *)&pinnedMap[5] + 4) = 0x5000000190LL;
*(__int64 *)((char *)&pinnedMap[6] + 4) = 0x2800000050LL;
*(__int64 *)((char *)&pinnedMap[7] + 4) = 0x2800000028LL;
*(__int64 *)((char *)&pinnedMap[8] + 4) = 0x3200000032LL;
result = 0x1E0000001ELL;
pinnedMap[10] = 0x1E0000001ELL;
return result;
}

canonical_decompiled_code:
__int64 func1()
{
__int64 result; // rax

pinnedMap[0] = 0xFFFFFFB0FFFFFE70LL;
pinnedMap[1] = 0xFFFFFFD8FFFFFFB0LL;
pinnedMap[2] = 0xFFFFFFD8FFFFFFD8LL;
pinnedMap[3] = 0xFFFFFFCEFFFFFFCELL;
*(__int64 *)((char *)&pinnedMap[4] + 4) = 0xFFFFFFE2FFFFFFE2LL;
*(__int64 *)((char *)&pinnedMap[5] + 4) = 0x5000000190LL;
*(__int64 *)((char *)&pinnedMap[6] + 4) = 0x2800000050LL;
*(__int64 *)((char *)&pinnedMap[7] + 4) = 0x2800000028LL;
*(__int64 *)((char *)&pinnedMap[8] + 4) = 0x3200000032LL;
result = 0x1E0000001ELL;
pinnedMap[10] = 0x1E0000001ELL;
return result;
}

original_code:
void initPinnedMap(void)
{
 pinnedMap[WHITE_QUEEN] = -(400);
 pinnedMap[WHITE_BEETLE_ONE] = -(80);
 pinnedMap[WHITE_BEETLE_TWO] = -(80);
 pinnedMap[WHITE_GRASSHOPPER_ONE] = -(40);
 pinnedMap[WHITE_GRASSHOPPER_TWO] = -(40);
 pinnedMap[WHITE_GRASSHOPPER_THREE] = -(40);
 pinnedMap[WHITE_ANT_ONE] = -(50);
 pinnedMap[WHITE_ANT_TWO] = -(50);
 pinnedMap[WHITE_ANT_TWO] = -(50);
 pinnedMap[WHITE_SPIDER_ONE] = -(30);
 pinnedMap[WHITE_SPIDER_TWO] = -(30);
 pinnedMap[BLACK_QUEEN] = (400);
 pinnedMap[BLACK_BEETLE_ONE] = (80);
 pinnedMap[BLACK_BEETLE_TWO] = (80);
 pinnedMap[BLACK_GRASSHOPPER_ONE] = (40);
 pinnedMap[BLACK_GRASSHOPPER_TWO] = (40);
 pinnedMap[BLACK_GRASSHOPPER_THREE] = (40);
 pinnedMap[BLACK_ANT_ONE] = (50);
 pinnedMap[BLACK_ANT_TWO] = (50);
 pinnedMap[BLACK_ANT_TWO] = (50);
 pinnedMap[BLACK_SPIDER_ONE] = (30);
 pinnedMap[BLACK_SPIDER_TWO] = (30);
}

canonical_original_code:
void initPinnedMap()
{
 pinnedMap[WHITE_QUEEN] = -(400);
 pinnedMap[WHITE_BEETLE_ONE] = -(80);
 pinnedMap[WHITE_BEETLE_TWO] = -(80);
 pinnedMap[WHITE_GRASSHOPPER_ONE] = -(40);
 pinnedMap[WHITE_GRASSHOPPER_TWO] = -(40);
 pinnedMap[WHITE_GRASSHOPPER_THREE] = -(40);
 pinnedMap[WHITE_ANT_ONE] = -(50);
 pinnedMap[WHITE_ANT_TWO] = -(50);
 pinnedMap[WHITE_ANT_TWO] = -(50);
 pinnedMap[WHITE_SPIDER_ONE] = -(30);
 pinnedMap[WHITE_SPIDER_TWO] = -(30);
 pinnedMap[BLACK_QUEEN] = (400);
 pinnedMap[BLACK_BEETLE_ONE] = (80);
 pinnedMap[BLACK_BEETLE_TWO] = (80);
 pinnedMap[BLACK_GRASSHOPPER_ONE] = (40);
 pinnedMap[BLACK_GRASSHOPPER_TWO] = (40);
 pinnedMap[BLACK_GRASSHOPPER_THREE] = (40);
 pinnedMap[BLACK_ANT_ONE] = (50);
 pinnedMap[BLACK_ANT_TWO] = (50);
 pinnedMap[BLACK_ANT_TWO] = (50);
 pinnedMap[BLACK_SPIDER_ONE] = (30);
 pinnedMap[BLACK_SPIDER_TWO] = (30);
}


parseTimeString

decompiled_code:
__int64 __fastcall parseTimeString(char *a1)
{
char *v1; // r13
char *v2; // r12
char *v3; // rbp
__int64 v4; // rbx
__int64 result; // rax

strtok(a1, "=,");
v1 = strtok(0LL, ",");
v2 = strtok(0LL, ",");
v3 = strtok(0LL, ",");
v4 = atol(v1) / 2;
totalGameTimePerPlayer = v4;
whiteRemainingTime = v4 - atol(v2);
result = atol(v3);
blackRemainingTime = v4 - result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *a1)
{
char *v1; // r13
char *v2; // r12
char *v3; // rbp
__int64 v4; // rbx
__int64 result; // rax

strtok(a1, "=,");
v1 = strtok(0LL, ",");
v2 = strtok(0LL, ",");
v3 = strtok(0LL, ",");
v4 = atol(v1) / 2;
totalGameTimePerPlayer = v4;
whiteRemainingTime = v4 - atol(v2);
result = atol(v3);
blackRemainingTime = v4 - result;
return result;
}

original_code:
void parseTimeString(char* timeString)
{
 char* totalTime;
 char* whiteUsedTime;
 char* blackUsedTime;
 totalTime = strtok(timeString, "=,");
 totalTime = strtok(((void *)0), ",");
 whiteUsedTime = strtok(((void *)0), ",");
 blackUsedTime = strtok(((void *)0), ",");
 totalGameTimePerPlayer = (uint32_t) (atol(totalTime) / 2);
 whiteRemainingTime = totalGameTimePerPlayer - (uint32_t)atol(whiteUsedTime);
 blackRemainingTime = totalGameTimePerPlayer - (uint32_t)atol(blackUsedTime);
}

canonical_original_code:
void parseTimeString(char *timeString)
{
 char *totalTime;
 char *whiteUsedTime;
 char *blackUsedTime;
 totalTime = strtok(timeString, "=,");
 totalTime = strtok(((void *)0), ",");
 whiteUsedTime = strtok(((void *)0), ",");
 blackUsedTime = strtok(((void *)0), ",");
 totalGameTimePerPlayer = (unsigned int) (atol(totalTime) / 2);
 whiteRemainingTime = totalGameTimePerPlayer - (unsigned int)atol(whiteUsedTime);
 blackRemainingTime = totalGameTimePerPlayer - (unsigned int)atol(blackUsedTime);
}

variable_types:
timeString
char *

variable_types:
totalTime
char *

variable_types:
whiteUsedTime
char *

variable_types:
blackUsedTime
char *

return_type: void


isWin

decompiled_code:
__int64 isWin()
{
unsigned int v0; // er12
unsigned __int8 v1; // bl
unsigned __int8 v2; // al
bool v3; // zf
bool v4; // bp
unsigned __int8 v5; // bl
unsigned __int8 v6; // al

v0 = 0;
v1 = getXpos(0LL);
v2 = getYpos(0LL);
v3 = (unsigned __int8)getNumberOfOccupiedSquaresAroundCoords(v1, v2) == 6;
if ( v3 )
v0 = -10000;
v4 = v3;
v5 = getXpos(11LL);
v6 = getYpos(11LL);
if ( (unsigned __int8)getNumberOfOccupiedSquaresAroundCoords(v5, v6) == 6 )
v0 = !v4 ? 10000 : 1;
return v0;
}

canonical_decompiled_code:
__int64 func0()
{
unsigned int v0; // er12
unsigned __int8 v1; // bl
unsigned __int8 v2; // al
bool v3; // zf
bool v4; // bp
unsigned __int8 v5; // bl
unsigned __int8 v6; // al

v0 = 0;
v1 = getXpos(0LL);
v2 = getYpos(0LL);
v3 = (unsigned __int8)getNumberOfOccupiedSquaresAroundCoords(v1, v2) == 6;
if ( v3 )
v0 = -10000;
v4 = v3;
v5 = getXpos(11LL);
v6 = getYpos(11LL);
if ( (unsigned __int8)getNumberOfOccupiedSquaresAroundCoords(v5, v6) == 6 )
v0 = !v4 ? 10000 : 1;
return v0;
}

original_code:
int isWin(void)
{
 int winScore = 0;
 uint8_t xpos, ypos;
 _Bool blackwin = 0;
 xpos = getXpos(WHITE_QUEEN);
 ypos = getYpos(WHITE_QUEEN);
 if (6 == getNumberOfOccupiedSquaresAroundCoords(xpos, ypos))
 {
  winScore = (-10000);
  blackwin = 1;
 }
 xpos = getXpos(BLACK_QUEEN);
 ypos = getYpos(BLACK_QUEEN);
 if (6 == getNumberOfOccupiedSquaresAroundCoords(xpos, ypos))
 {
  winScore = (10000);
  if (blackwin)
   winScore = (1);
 }
 return winScore;
}

canonical_original_code:
int isWin()
{
 int winScore = 0;
 unsigned char xpos; unsigned char ypos;
 _Bool blackwin = 0;
 xpos = getXpos(WHITE_QUEEN);
 ypos = getYpos(WHITE_QUEEN);
 if (6 == getNumberOfOccupiedSquaresAroundCoords(xpos, ypos))
 {
  winScore = (-10000);
  blackwin = 1;
 }
 xpos = getXpos(BLACK_QUEEN);
 ypos = getYpos(BLACK_QUEEN);
 if (6 == getNumberOfOccupiedSquaresAroundCoords(xpos, ypos))
 {
  winScore = (10000);
  if (blackwin)
   winScore = (1);
 }
 return winScore;
}

variable_types: winScore int

variable_types:
xpos
unsigned char

variable_types:
ypos
unsigned char

return_type: int


repo: yeison/banker-s

decompiled_code:
__int64 __fastcall pop_back(unsigned int **a1)
{
unsigned int *v1; // rax
unsigned int v2; // er8
__int64 v3; // rax
__int64 result; // rax

v1 = *a1;
if ( !*a1 )
return 0LL;
v2 = *v1;
if ( v1 == a1[1] )
{
a1[1] = 0LL;
result = v2;
*a1 = 0LL;
}
else
{
v3 = *((_QWORD *)v1 + 1);
*a1 = (unsigned int *)v3;
*(_QWORD *)(v3 + 16) = 0LL;
result = v2;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int **a1)
{
unsigned int *v1; // rax
unsigned int v2; // er8
__int64 v3; // rax
__int64 result; // rax

v1 = *a1;
if ( !*a1 )
return 0LL;
v2 = *v1;
if ( v1 == a1[1] )
{
a1[1] = 0LL;
result = v2;
*a1 = 0LL;
}
else
{
v3 = *((_QWORD *)v1 + 1);
*a1 = (unsigned int *)v3;
*(_QWORD *)(v3 + 16) = 0LL;
result = v2;
}
return result;
}

original_code:
int pop_back( queue *queue ){
    if(queue->head == ((void *)0)){
        return ((void *)0);
    }
    int value = queue->head->value;
    queue_int *head = queue->head;
    if (queue->head == queue->tail) {
        queue->head = queue->tail = ((void *)0);
    } else {
        queue->head = head->next;
        queue->head->previous = ((void *)0);
    }
    return value;
}

canonical_original_code:
int pop_back(struct queue *queue){
    if(queue->head == ((void *)0)){
        return ((void *)0);
    }
    int value = queue->head->value;
    struct queue_int *head = queue->head;
    if (queue->head == queue->tail) {
        queue->head = queue->tail = ((void *)0);
    } else {
        queue->head = head->next;
        queue->head->previous = ((void *)0);
    }
    return value;
}

variable_types: struct queue { struct queue_int { int value; struct queue_int *next; struct queue_int *previous; } *head; struct queue_int *tail; } *

variable_types: value int

user_defined_types: struct queue { struct queue_int *head; struct queue_int *tail; }


decompiled_code:
__int64 __fastcall pop_front(int **a1)
{
unsigned int *v1; // rax
unsigned int v2; // er8
__int64 v3; // rax
__int64 result; // rax

v1 = (unsigned int *)a1[1];
if ( !v1 )
return 0LL;
v2 = *v1;
if ( v1 == (unsigned int *)*a1 )
{
a1[1] = 0LL;
result = v2;
*a1 = 0LL;
}
else
{
v3 = *((_QWORD *)v1 + 2);
a1[1] = (int *)v3;
*(_QWORD *)(v3 + 8) = 0LL;
result = v2;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int **a1)
{
unsigned int *v1; // rax
unsigned int v2; // er8
__int64 v3; // rax
__int64 result; // rax

v1 = (unsigned int *)a1[1];
if ( !v1 )
return 0LL;
v2 = *v1;
if ( v1 == (unsigned int *)*a1 )
{
a1[1] = 0LL;
result = v2;
*a1 = 0LL;
}
else
{
v3 = *((_QWORD *)v1 + 2);
a1[1] = (int *)v3;
*(_QWORD *)(v3 + 8) = 0LL;
result = v2;
}
return result;
}

original_code:
int pop_front( queue *queue ){
    if(queue->tail == ((void *)0)){
        return ((void *)0);
    }
    int value = queue->tail->value;
    queue_int *tail = queue->tail;
    if (queue->head == queue->tail) {
        queue->head = queue->tail = ((void *)0);
    } else {
        queue->tail = tail->previous;
        queue->tail->next = ((void *)0);
    }
    return value;
}

canonical_original_code:
int pop_front(struct queue *queue){
    if(queue->tail == ((void *)0)){
        return ((void *)0);
    }
    int value = queue->tail->value;
    struct queue_int *tail = queue->tail;
    if (queue->head == queue->tail) {
        queue->head = queue->tail = ((void *)0);
    } else {
        queue->tail = tail->previous;
        queue->tail->next = ((void *)0);
    }
    return value;
}

variable_types: struct queue_int { int value; struct queue_int *next; struct queue_int *previous; } *


decompiled_code:
bool __fastcall is_empty(_QWORD *a1)
{
bool result; // al

result = 0;
if ( !*a1 )
result = a1[1] == 0LL;
return result;
}

canonical_decompiled_code:
bool __fastcall func2(_QWORD *a1)
{
bool result; // al

result = 0;
if ( !*a1 )
result = a1[1] == 0LL;
return result;
}

original_code:
_Bool is_empty( queue *queue ){
    if (queue->head == ((void *)0) && queue->tail == ((void *)0)) {
        return 1;
    }
    return 0;
}

canonical_original_code:
_Bool is_empty(struct queue *queue){
    if (queue->head == ((void *)0) && queue->tail == ((void *)0)) {
        return 1;
    }
    return 0;
}

user_defined_types: struct queue_int { int value; struct queue_int *next; struct queue_int *previous; }


printQueues

decompiled_code:
void __fastcall printQueues(__int64 a1, int a2)
{
__int64 v2; // rbp
__int64 i; // rbx
unsigned int v4; // er15
unsigned int v5; // er14
const char *v6; // rax

if ( a2 > 0 )
{
v2 = 1LL;
do
{
printf("\nTask %d:\n", (unsigned int)v2);
for ( i = *(_QWORD *)(a1 + 8 * v2 - 8); i; i = *(_QWORD *)(i + 24) )
{
v4 = *(_DWORD *)(i + 16);
v5 = *(_DWORD *)(i + 12) + 1;
v6 = (const char *)getActivityType(*(unsigned int *)(i + 8));
printf("\t%2d %2d %10s %2d %2d\n", (unsigned int)(*(_DWORD *)i + 1), *(unsigned int *)(i + 4), v6, v5, v4);
}
++v2;
}
while ( a2 + 1 != v2 );
}
}

canonical_decompiled_code:
void __fastcall func0(__int64 a1, int a2)
{
__int64 v2; // rbp
__int64 i; // rbx
unsigned int v4; // er15
unsigned int v5; // er14
const char *v6; // rax

if ( a2 > 0 )
{
v2 = 1LL;
do
{
printf("\nTask %d:\n", (unsigned int)v2);
for ( i = *(_QWORD *)(a1 + 8 * v2 - 8); i; i = *(_QWORD *)(i + 24) )
{
v4 = *(_DWORD *)(i + 16);
v5 = *(_DWORD *)(i + 12) + 1;
v6 = (const char *)getActivityType(*(unsigned int *)(i + 8));
printf("\t%2d %2d %10s %2d %2d\n", (unsigned int)(*(_DWORD *)i + 1), *(unsigned int *)(i + 4), v6, v5, v4);
}
++v2;
}
while ( a2 + 1 != v2 );
}
}

original_code:
void printQueues(activity** taskTable, int numberOfTasks){
    for (int i=0; i < numberOfTasks; i++) {
        printf("\nTask %d:\n", i+1);
        activity *tempActivity = taskTable[i];
        while (tempActivity != ((void *)0)) {
            printf("\t%2d %2d %10s %2d %2d\n",
                   tempActivity->taskNumber+1,
                   tempActivity->delay,
                   getActivityType(tempActivity->type),
                   tempActivity->resourceType+1,
                   tempActivity->resourceAmount);
            tempActivity = tempActivity->next;
        }
    }
}

canonical_original_code:
void printQueues(struct activity **taskTable, int numberOfTasks){
    for (int i = 0; i < numberOfTasks; i++) {
        printf("\nTask %d:\n", i+1);
        struct activity *tempActivity = taskTable[i];
        while (tempActivity != ((void *)0)) {
            printf("\t%2d %2d %10s %2d %2d\n",
                   tempActivity->taskNumber+1,
                   tempActivity->delay,
                   getActivityType(tempActivity->type),
                   tempActivity->resourceType+1,
                   tempActivity->resourceAmount);
            tempActivity = tempActivity->next;
        }
    }
}

variable_types: struct activity { int taskNumber; int delay; int type; int resourceType; int resourceAmount; int currentState; struct activity *next; } **

variable_types: numberOfTasks int

variable_types: i int


getActivityTypeValue

decompiled_code:
__int64 __fastcall getActivityTypeValue(const char *a1)
{
if ( !strcmp(a1, "initiate") )
return 2LL;
if ( !strcmp(a1, "request") )
return 3LL;
if ( !strcmp(a1, "release") )
return 4LL;
if ( strcmp(a1, "terminate") )
{
perror("Activity type requested is unknown. Please use proper formatting.");
exit(2);
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char *a1)
{
if ( !strcmp(a1, "initiate") )
return 2LL;
if ( !strcmp(a1, "request") )
return 3LL;
if ( !strcmp(a1, "release") )
return 4LL;
if ( strcmp(a1, "terminate") )
{
perror("Activity type requested is unknown. Please use proper formatting.");
exit(2);
}
return 1LL;
}

original_code:
int getActivityTypeValue(char *type){
 if(!strcmp(type, "initiate"))
  return 2;
 else if(!strcmp(type, "request"))
  return 3;
 else if(!strcmp(type, "release"))
  return 4;
 else if(!strcmp(type, "terminate"))
  return 1;
 else {
  perror("Activity type requested is unknown.  Please use proper formatting.");
  exit(2);
 }
}

variable_types:
type
char *


makeActivityQueues

decompiled_code:
__int64 __fastcall makeActivityQueues(__int64 a1, __int64 a2)
{
__int64 v2; // rdx
__int64 v3; // rdx
__int64 result; // rax
__int64 v5; // r12
_DWORD *v6; // rax
__int64 v7; // rcx
int v8[7]; // [rsp+Ch] [rbp-1Ch] BYREF

while ( 1 )
{
result = _isoc99_scanf("%d", v8);
if ( (_DWORD)result == -1 )
break;
v5 = *(_QWORD *)(a2 + 8LL * v8[0] - 8);
v6 = makeActivityNode(v8[0] - 1);
if ( v5 )
{
v2 = v8[0];
*(_QWORD *)(v5 + 24) = v6;
v3 = 8 * v2 - 8;
}
else
{
v7 = 8LL * v8[0];
*(_QWORD *)(a1 + v7 - 8) = v6;
v3 = v7 - 8;
}
*(_QWORD *)(a2 + v3) = v6;
}
return result;
}

original_code:
void makeActivityQueues(activity *taskTable[], activity *taskTableTails[]){
 int currentTask;
 activity *currentActivityPtr;
 while(scanf("%d", &currentTask) != (-1)){
        if (taskTableTails[currentTask-1]){
            currentActivityPtr = taskTableTails[currentTask-1];
            currentActivityPtr->next = makeActivityNode(currentTask-1);
            currentActivityPtr = currentActivityPtr->next;
        }
        else {
            currentActivityPtr = makeActivityNode(currentTask-1);
            taskTable[currentTask-1] = currentActivityPtr;
        }
        taskTableTails[currentTask-1] = currentActivityPtr;
    }
}

canonical_original_code:
void makeActivityQueues(struct activity *taskTable[], struct activity *taskTableTails[]){
 int currentTask;
 struct activity *currentActivityPtr;
 while(scanf("%d", &currentTask) != (-1)){
        if (taskTableTails[currentTask-1]){
            currentActivityPtr = taskTableTails[currentTask-1];
            currentActivityPtr->next = makeActivityNode(currentTask-1);
            currentActivityPtr = currentActivityPtr->next;
        }
        else {
            currentActivityPtr = makeActivityNode(currentTask-1);
            taskTable[currentTask-1] = currentActivityPtr;
        }
        taskTableTails[currentTask-1] = currentActivityPtr;
    }
}

variable_types: struct activity { int taskNumber; int delay; int type; int resourceType; int resourceAmount; int currentState; struct activity *next; } *[]

variable_types:
taskTableTails
struct activity *[]

variable_types: currentTask int


getActivityType

decompiled_code:
char *__fastcall getActivityType(int a1)
{
__int64 v1; // rdi
char *result; // rax

v1 = (unsigned int)(a1 - 1);
result = (char *)&unk_201;
if ( (unsigned int)v1 <= 3 )
result = CSWTCH_10[v1];
return result;
}

canonical_decompiled_code:
char *__fastcall func2(int a1)
{
__int64 v1; // rdi
char *result; // rax

v1 = (unsigned int)(a1 - 1);
result = (char *)&unk_201;
if ( (unsigned int)v1 <= 3 )
result = CSWTCH_10[v1];
return result;
}

original_code:
char* getActivityType(int activityTypeValue){
    switch (activityTypeValue) {
        case 2:
            return "initiate";
        case 3:
            return "request";
        case 4:
            return "release";
        case 1:
            return "terminate";
        default:
            return "";
    }
}

canonical_original_code:
char *getActivityType(int activityTypeValue){
    switch (activityTypeValue) {
        case 2:
            return "initiate";
        case 3:
            return "request";
        case 4:
            return "release";
        case 1:
            return "terminate";
        default:
            return "";
    }
}

variable_types: activityTypeValue int

return_type: char *


repo: yrutschle/sslh

decompiled_code:
void __fastcall stop_listeners(int sig)
{
__pid_t *v1; // rax
__int64 v2; // rbx
__int64 v3; // r12

if ( listener_pid_number > 0 )
{
v1 = (__pid_t *)listener_pid;
v2 = listener_pid + 4;
v3 = listener_pid + 4 + 4LL * (unsigned int)(listener_pid_number - 1);
while ( 1 )
{
kill(*v1, sig);
v1 = (__pid_t *)v2;
if ( v2 == v3 )
break;
v2 += 4LL;
}
}
}

canonical_decompiled_code:
void __fastcall func0(int sig)
{
__pid_t *v1; // rax
__int64 v2; // rbx
__int64 v3; // r12

if ( listener_pid_number > 0 )
{
v1 = (__pid_t *)listener_pid;
v2 = listener_pid + 4;
v3 = listener_pid + 4 + 4LL * (unsigned int)(listener_pid_number - 1);
while ( 1 )
{
kill(*v1, sig);
v1 = (__pid_t *)v2;
if ( v2 == v3 )
break;
v2 += 4LL;
}
}
}

original_code:
void stop_listeners(int sig)
{
    int i;
    for (i = 0; i < listener_pid_number; i++) {
        kill(listener_pid[i], sig);
    }
}

variable_types: sig int


shovel

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

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

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

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

variable_types: res int

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

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

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


decompiled_code:
void set_listen_procname()
{
;
}

canonical_decompiled_code:
void func3()
{
;
}

original_code:
void set_listen_procname(struct listen_endpoint *listen_socket)
{
}

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


decompiled_code:
__int64 __fastcall tcp_listener(int *a1, int a2, int a3)
{
int *v3; // r12
int *v4; // rbx
int *v5; // r14
char *v6; // rax
unsigned int v7; // eax
int v8; // ebp
__pid_t v9; // eax
__int64 v10; // rbx
int v11; // edi
int *v12; // rbx
char *v13; // rax
__int64 v15; // [rsp-10h] [rbp-38h]

v3 = a1;
v4 = &a1[2 * a3];
while ( 1 )
{
v7 = accept(*v4, 0LL, 0LL);
v8 = v7;
if ( v7 == -1 )
break;
print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "accepted fd %d\n", v7);
v9 = fork();
if ( v9 == -1 )
{
v5 = _errno_location();
v6 = strerror(*v5);
print_message(
msg_system_error,
*((_QWORD *)&msg_system_error + 1),
"fork failed: err %d: %s\n",
(unsigned int)*v5,
v6);
}
else if ( !v9 )
{
if ( a2 > 0 )
{
v10 = (__int64)&a1[2 * (a2 - 1) + 2];
do
{
v11 = *v3;
v3 += 2;
close(v11);
}
while ( v3 != (int *)v10 );
}
start_shoveler(v8);
}
close(v8);
}
v12 = _errno_location();
v13 = strerror(*v12);
print_message(
msg_system_error,
*((_QWORD *)&msg_system_error + 1),
"%s:%d:%s:%d:%s\n",
"sslh-fork.c",
180LL,
"accept",
(unsigned int)*v12,
v13);
return v15;
}

canonical_decompiled_code:
__int64 __fastcall func4(int *a1, int a2, int a3)
{
int *v3; // r12
int *v4; // rbx
int *v5; // r14
char *v6; // rax
unsigned int v7; // eax
int v8; // ebp
__pid_t v9; // eax
__int64 v10; // rbx
int v11; // edi
int *v12; // rbx
char *v13; // rax
__int64 v15; // [rsp-10h] [rbp-38h]

v3 = a1;
v4 = &a1[2 * a3];
while ( 1 )
{
v7 = accept(*v4, 0LL, 0LL);
v8 = v7;
if ( v7 == -1 )
break;
print_message(msg_fd, *((_QWORD *)&msg_fd + 1), "accepted fd %d\n", v7);
v9 = fork();
if ( v9 == -1 )
{
v5 = _errno_location();
v6 = strerror(*v5);
print_message(
msg_system_error,
*((_QWORD *)&msg_system_error + 1),
"fork failed: err %d: %s\n",
(unsigned int)*v5,
v6);
}
else if ( !v9 )
{
if ( a2 > 0 )
{
v10 = (__int64)&a1[2 * (a2 - 1) + 2];
do
{
v11 = *v3;
v3 += 2;
close(v11);
}
while ( v3 != (int *)v10 );
}
func2(v8);
}
close(v8);
}
v12 = _errno_location();
v13 = strerror(*v12);
print_message(
msg_system_error,
*((_QWORD *)&msg_system_error + 1),
"%s:%d:%s:%d:%s\n",
"sslh-fork.c",
180LL,
"accept",
(unsigned int)*v12,
v13);
return v15;
}

original_code:
void tcp_listener(struct listen_endpoint* endpoint, int num_endpoints, int active_endpoint)
{
    int i, in_socket;
    while (1) {
        in_socket = accept(endpoint[active_endpoint].socketfd, 0, 0);
        if (in_socket == -1) { print_message(msg_system_error, "%s:%d:%s:%d:%s\n", "sslh-fork.c", 180, "accept", (*__errno_location ()), strerror((*__errno_location ()))); return ; };
        print_message(msg_fd, "accepted fd %d\n", in_socket);
        switch(fork()) {
        case -1: print_message(msg_system_error, "fork failed: err %d: %s\n", (*__errno_location ()), strerror((*__errno_location ())));
                 break;
        case 0:
                 for (i = 0; i < num_endpoints; i++)
                     close(endpoint[i].socketfd);
                 start_shoveler(in_socket);
                 exit(0);
        default:
                 break;
        }
        close(in_socket);
    }
}

canonical_original_code:
void tcp_listener(struct listen_endpoint *endpoint, int num_endpoints, int active_endpoint)
{
    int i; int in_socket;
    while (1) {
        in_socket = accept(endpoint[active_endpoint].socketfd, 0, 0);
        if (in_socket == -1) { print_message(msg_system_error, "%s:%d:%s:%d:%s\n", "sslh-fork.c", 180, "accept", (*__errno_location ()), strerror((*__errno_location ()))); return ; };
        print_message(msg_fd, "accepted fd %d\n", in_socket);
        switch(fork()) {
        case -1: print_message(msg_system_error, "fork failed: err %d: %s\n", (*__errno_location ()), strerror((*__errno_location ())));
                 break;
        case 0:
                 for (i = 0; i < num_endpoints; i++)
                     close(endpoint[i].socketfd);
                 start_shoveler(in_socket);
                 exit(0);
        default:
                 break;
        }
        close(in_socket);
    }
}

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


decompiled_code:
void __fastcall __noreturn start_shoveler(int fd)
{
unsigned int v2; // er14
__int64 v3; // rbx
__time_t v4; // rax
__int64 v5; // rbp
const char *v6; // rdi
const char **v7; // rax
__int64 v8; // rsi
const char *v9; // rcx
int v10; // ebp
struct timeval v11; // [rsp+0h] [rbp-11E8h] BYREF
fd_set readfds; // [rsp+10h] [rbp-11D8h] BYREF
char v13[8]; // [rsp+90h] [rbp-1158h] BYREF
const char **v14; // [rsp+98h] [rbp-1150h]
int v15; // [rsp+B0h] [rbp-1138h]
int v16[24]; // [rsp+D0h] [rbp-1118h] BYREF
char v17[4280]; // [rsp+130h] [rbp-10B8h] BYREF

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

canonical_decompiled_code:
void __fastcall __noreturn func2(int fd)
{
unsigned int v2; // er14
__int64 v3; // rbx
__time_t v4; // rax
__int64 v5; // rbp
const char *v6; // rdi
const char **v7; // rax
__int64 v8; // rsi
const char *v9; // rcx
int v10; // ebp
struct timeval v11; // [rsp+0h] [rbp-11E8h] BYREF
fd_set readfds; // [rsp+10h] [rbp-11D8h] BYREF
char v13[8]; // [rsp+90h] [rbp-1158h] BYREF
const char **v14; // [rsp+98h] [rbp-1150h]
int v15; // [rsp+B0h] [rbp-1138h]
int v16[24]; // [rsp+D0h] [rbp-1118h] BYREF
char v17[4280]; // [rsp+130h] [rbp-10B8h] BYREF

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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


decompiled_code:
int __fastcall print_udp_xchange(int a1, __int64 a2)
{
char *v2; // r12
char *v3; // rax
__int64 v5; // [rsp+0h] [rbp-948h] BYREF
socklen_t len; // [rsp+10h] [rbp-938h] BYREF
struct sockaddr *v7; // [rsp+18h] [rbp-930h]
char v8[16]; // [rsp+30h] [rbp-918h] BYREF
int v9; // [rsp+40h] [rbp-908h]
__int64 v10; // [rsp+48h] [rbp-900h]
struct sockaddr addr; // [rsp+60h] [rbp-8E8h] BYREF
char v12[1072]; // [rsp+E0h] [rbp-868h] BYREF
char s[1080]; // [rsp+510h] [rbp-438h] BYREF

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

canonical_decompiled_code:
int __fastcall func3(int a1, __int64 a2)
{
char *v2; // r12
char *v3; // rax
__int64 v5; // [rsp+0h] [rbp-948h] BYREF
socklen_t len; // [rsp+10h] [rbp-938h] BYREF
struct sockaddr *v7; // [rsp+18h] [rbp-930h]
char v8[16]; // [rsp+30h] [rbp-918h] BYREF
int v9; // [rsp+40h] [rbp-908h]
__int64 v10; // [rsp+48h] [rbp-900h]
struct sockaddr addr; // [rsp+60h] [rbp-8E8h] BYREF
char v12[1072]; // [rsp+E0h] [rbp-868h] BYREF
char s[1080]; // [rsp+510h] [rbp-438h] BYREF

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

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

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

variable_types: sockfd int

variable_types:
addrlen
unsigned int

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

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


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

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

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

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

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

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

variable_types:
data
char [65536]

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

variable_types:
len
unsigned long


main

canonical_name: main

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

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

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

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

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

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
optarg
char *

variable_types: optind int


sprintaddr

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

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

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

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

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

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

variable_types:
buf
char *

variable_types:
size
unsigned long

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

variable_types:
host
char [1025]

variable_types:
serv
char [32]

variable_types: res int


decompiled_code:
void __fastcall check_res_dump(int a1, __int64 a2, const char *a3)
{
__int64 v3; // rbx
__int64 v4; // r12
int *v6; // rax
char *v7; // rbx
char *v8; // rax
char s[1048]; // [rsp+8h] [rbp-428h] BYREF
__int64 v10; // [rsp+420h] [rbp-10h]
__int64 v11; // [rsp+428h] [rbp-8h]

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

canonical_decompiled_code:
void __fastcall func2(int a1, __int64 a2, const char *a3)
{
__int64 v3; // rbx
__int64 v4; // r12
int *v6; // rax
char *v7; // rbx
char *v8; // rax
char s[1048]; // [rsp+8h] [rbp-428h] BYREF
__int64 v10; // [rsp+420h] [rbp-10h]
__int64 v11; // [rsp+428h] [rbp-8h]

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

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

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

variable_types:
syscall
char *

variable_types:
buf
char [1025]

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


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

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

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

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

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

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

variable_types: i int


decompiled_code:
__int64 __fastcall listen_single_addr(__int64 a1, __int64 a2, int a3)
{
unsigned int v4; // er12
int v5; // eax
const struct sockaddr *v6; // rsi
int v7; // eax
int v9; // eax
int v10; // eax
int optval[7]; // [rsp+Ch] [rbp-1Ch] BYREF

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

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2, int a3)
{
unsigned int v4; // er12
int v5; // eax
const struct sockaddr *v6; // rsi
int v7; // eax
int v9; // eax
int v10; // eax
int optval[7]; // [rsp+Ch] [rbp-1Ch] BYREF

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

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

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

variable_types: keepalive int

variable_types: udp int

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

variable_types: sockfd int

variable_types: one int


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

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

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

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

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

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

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

variable_types:
host
char *

variable_types:
serv
char *

variable_types:
end
char *


decompiled_code:
__int64 __fastcall start_listen_sockets(void **a1)
{
int v1; // er15
struct addrinfo *v2; // r14
size_t v3; // rbp
char *v4; // rax
char *v5; // rax
__int64 v6; // rdx
unsigned int v8; // [rsp+0h] [rbp-468h]
unsigned __int64 v9; // [rsp+8h] [rbp-460h]
struct addrinfo *ai; // [rsp+18h] [rbp-450h] BYREF
char s[1096]; // [rsp+20h] [rbp-448h] BYREF

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

canonical_decompiled_code:
__int64 __fastcall func8(void **a1)
{
int v1; // er15
struct addrinfo *v2; // r14
size_t v3; // rbp
char *v4; // rax
char *v5; // rax
__int64 v6; // rdx
unsigned int v8; // [rsp+0h] [rbp-468h]
unsigned __int64 v9; // [rsp+8h] [rbp-460h]
struct addrinfo *ai; // [rsp+18h] [rbp-450h] BYREF
char s[1096]; // [rsp+20h] [rbp-448h] BYREF

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

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

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

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

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


distance

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

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

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

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

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

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

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

variable_types:
item
void *

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


decompiled_code:
__int64 __fastcall hash_find_index(__int64 a1, __int64 a2)
{
unsigned int v3; // ebp
__int64 v4; // rax
int v5; // ecx
__int64 v6; // rdi
int v7; // er13

v3 = hash_make_key(a1, a2);
v4 = gap_get(*(_QWORD *)(a1 + 8), v3);
if ( v4 )
{
v5 = *(_DWORD *)a1;
v6 = v4;
v7 = 0;
do
{
if ( v5 < v7 )
break;
if ( !(*(unsigned int (__fastcall **)(__int64, __int64))(a1 + 24))(v6, a2) )
return v3;
++v7;
v3 = hash_next_index_isra_0(*(_DWORD *)a1, v3);
v6 = gap_get(*(_QWORD *)(a1 + 8), v3);
}
while ( v6 );
}
return (unsigned int)-1;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, __int64 a2)
{
unsigned int v3; // ebp
__int64 v4; // rax
int v5; // ecx
__int64 v6; // rdi
int v7; // er13

v3 = func1(a1, a2);
v4 = func0(*(_QWORD *)(a1 + 8), v3);
if ( v4 )
{
v5 = *(_DWORD *)a1;
v6 = v4;
v7 = 0;
do
{
if ( v5 < v7 )
break;
if ( !(*(unsigned int (__fastcall **)(__int64, __int64))(a1 + 24))(v6, a2) )
return v3;
++v7;
v3 = func3(*(_DWORD *)a1, v3);
v6 = func0(*(_QWORD *)(a1 + 8), v3);
}
while ( v6 );
}
return (unsigned int)-1;
}

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

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

variable_types:
cnx
void *

variable_types: index int

variable_types: cnt int

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


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

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

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

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

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

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

variable_types:
out
void *

return_type: void *


decompiled_code:
__int64 __fastcall hash_insert(__int64 a1, __int64 a2)
{
__int64 v2; // r13
int v3; // eax
__int64 v4; // r14
int v5; // ebp
__int64 v6; // rax
__int64 v7; // rbx
int v8; // er15
__int64 v9; // rdx

v2 = a2;
v3 = hash_make_key(a1, a2);
v4 = *(_QWORD *)(a1 + 8);
v5 = v3;
if ( *(_DWORD *)(a1 + 4) == *(_DWORD *)a1 )
return 0xFFFFFFFFLL;
while ( 1 )
{
v6 = gap_get(v4, v5);
v7 = v6;
if ( !v6 )
break;
v8 = distance(v5, (_DWORD *)a1, v6);
if ( v8 < (int)distance(v5, (_DWORD *)a1, v2) )
{
v9 = v2;
v2 = v7;
gap_set_isra_0(*(_QWORD *)(a1 + 8), v5, v9);
}
v5 = hash_next_index_isra_0(*(_DWORD *)a1, v5);
}
gap_set_isra_0(v4, v5, v2);
++*(_DWORD *)(a1 + 4);
return 0LL;
}

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

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

variable_types:
new
void *

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


decompiled_code:
__int64 __fastcall hash_remove(__int64 a1, __int64 a2)
{
__int64 v3; // r13
unsigned int v4; // ebp
int v5; // edi
int v6; // eax
__int64 v7; // rax
int v8; // er8
__int64 v9; // r12
int v10; // esi

v3 = *(_QWORD *)(a1 + 8);
v4 = hash_find_index(a1, a2);
if ( v4 != -1 )
{
v5 = *(_DWORD *)a1;
while ( 1 )
{
v6 = hash_next_index_isra_0(v5, v4);
v7 = gap_get(*(_QWORD *)(a1 + 8), v6);
v9 = v7;
if ( !v7 || !(unsigned int)distance(v8, (_DWORD *)a1, v7) )
break;
gap_set_isra_0(v3, v4, v9);
v5 = *(_DWORD *)a1;
v4 = hash_next_index_isra_0(*(_DWORD *)a1, v4);
}
--*(_DWORD *)(a1 + 4);
v10 = v4;
v4 = 0;
gap_set_isra_0(v3, v10, 0LL);
}
return v4;
}

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

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

variable_types:
next
void *


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

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

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

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

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

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

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

variable_types:
str
char *


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

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

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

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

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

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

variable_types: res int

variable_types: fn int


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

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

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

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

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


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

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

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

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

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


decompiled_code:
int __fastcall log_connection(const char *a1, __int64 a2)
{
const char **v2; // rax
const char *v3; // r8
bool v4; // zf
int v6; // [rsp-10A8h] [rbp-10A8h]
_BYTE v7[4248]; // [rsp-1098h] [rbp-1098h] BYREF

v2 = *(const char ***)(a2 + 8);
if ( *((int *)v2 + 16) > 0 )
{
v3 = a1;
if ( a1 )
{
LABEL_3:
print_message(
msg_connections,
*((int **)&msg_connections + 1),
"%s:connection from %s to %s forwarded from %s to %s\n",
*v2,
v3,
v3 + 1058,
v3 + 2116,
v3 + 3174);
LODWORD(v2) = v6;
return (int)v2;
}
v4 = (unsigned int)get_connection_desc(v7) == 0;
v2 = *(const char ***)(a2 + 8);
if ( !v4 )
{
v3 = v7;
goto LABEL_3;
}
LODWORD(v2) = print_message(msg_connections, *((int **)&msg_connections + 1), "%s: lost incoming connection\n", *v2);
}
return (int)v2;
}

canonical_decompiled_code:
int __fastcall func4(const char *a1, __int64 a2)
{
const char **v2; // rax
const char *v3; // r8
bool v4; // zf
int v6; // [rsp-10A8h] [rbp-10A8h]
_BYTE v7[4248]; // [rsp-1098h] [rbp-1098h] BYREF

v2 = *(const char ***)(a2 + 8);
if ( *((int *)v2 + 16) > 0 )
{
v3 = a1;
if ( a1 )
{
LABEL_3:
func0(
msg_connections,
*((int **)&msg_connections + 1),
"%s:connection from %s to %s forwarded from %s to %s\n",
*v2,
v3,
v3 + 1058,
v3 + 2116,
v3 + 3174);
LODWORD(v2) = v6;
return (int)v2;
}
v4 = (unsigned int)get_connection_desc(v7) == 0;
v2 = *(const char ***)(a2 + 8);
if ( !v4 )
{
v3 = v7;
goto LABEL_3;
}
LODWORD(v2) = func0(msg_connections, *((int **)&msg_connections + 1), "%s: lost incoming connection\n", *v2);
}
return (int)v2;
}

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

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

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

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


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

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

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

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

variable_types: fd int

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

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

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


shovel

decompiled_code:
__int64 __fastcall shovel(__int64 a1, int a2, __int64 a3)
{
__int64 v3; // r14
unsigned int *v5; // rbx
__int64 result; // rax

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

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, int a2, __int64 a3)
{
__int64 v3; // r14
unsigned int *v5; // rbx
__int64 result; // rax

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

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

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

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

variable_types: i int