// File: /workspace/github_c_makefile_star2_O3/jech[P]dht/dht.c
// Function: new_node
static struct node *
new_node(const unsigned char *id, const struct sockaddr *sa, int salen,
         int confirm)
{
    struct bucket *b;
    struct node *n;
    int mybucket;

 again:

    b = find_bucket(id, sa->sa_family);
    if(b == NULL)
        return NULL;

    if(id_cmp(id, myid) == 0)
        return NULL;

    if(is_martian(sa) || node_blacklisted(sa, salen))
        return NULL;

    mybucket = in_bucket(myid, b);

    if(confirm == 2)
        b->time = now.tv_sec;

    n = b->nodes;
    while(n) {
        if(id_cmp(n->id, id) == 0) {
            if(confirm || n->time < now.tv_sec - 15 * 60) {
                /* Known node.  Update stuff. */
                memcpy((struct sockaddr*)&n->ss, sa, salen);
                if(confirm)
                    n->time = now.tv_sec;
                if(confirm >= 2) {
                    n->reply_time = now.tv_sec;
                    n->pinged = 0;
                    n->pinged_time = 0;
                }
            }
            if(confirm == 2)
                add_search_node(id, sa, salen);
            return n;
        }
        n = n->next;
    }

    /* New node. */

    if(mybucket) {
        if(sa->sa_family == AF_INET)
            mybucket_grow_time = now.tv_sec;
        else
            mybucket6_grow_time = now.tv_sec;
    }

    /* First, try to get rid of a known-bad node. */
    n = b->nodes;
    while(n) {
        if(n->pinged >= 3 && n->pinged_time < now.tv_sec - 15) {
            memcpy(n->id, id, 20);
            memcpy((struct sockaddr*)&n->ss, sa, salen);
            n->time = confirm ? now.tv_sec : 0;
            n->reply_time = confirm >= 2 ? now.tv_sec : 0;
            n->pinged_time = 0;
            n->pinged = 0;
            if(confirm == 2)
                add_search_node(id, sa, salen);
            return n;
        }
        n = n->next;
    }

    if(b->count >= b->max_count) {
        /* Bucket full.  Ping a dubious node */
        int dubious = 0;
        n = b->nodes;
        while(n) {
            /* Pick the first dubious node that we haven't pinged in the
               last 15 seconds.  This gives nodes the time to reply, but
               tends to concentrate on the same nodes, so that we get rid
               of bad nodes fast. */
            if(!node_good(n)) {
                dubious = 1;
                if(n->pinged_time < now.tv_sec - 15) {
                    unsigned char tid[4];
                    debugf("Sending ping to dubious node.\n");
                    make_tid(tid, "pn", 0);
                    send_ping((struct sockaddr*)&n->ss, n->sslen,
                              tid, 4);
                    n->pinged++;
                    n->pinged_time = now.tv_sec;
                    break;
                }
            }
            n = n->next;
        }

        if(mybucket && !dubious) {
            int rc;
            rc = split_bucket(b);
            if(rc > 0)
                goto again;
            return NULL;
        }

        /* No space for this node.  Cache it away for later. */
        if(confirm || b->cached.ss_family == 0) {
            memcpy(&b->cached, sa, salen);
            b->cachedlen = salen;
        }

        if(confirm == 2)
            add_search_node(id, sa, salen);
        return NULL;
    }

    /* Create a new node. */
    n = calloc(1, sizeof(struct node));
    if(n == NULL)
        return NULL;
    memcpy(n->id, id, 20);
    memcpy(&n->ss, sa, salen);
    n->sslen = salen;
    n->time = confirm ? now.tv_sec : 0;
    n->reply_time = confirm >= 2 ? now.tv_sec : 0;
    n->next = b->nodes;
    b->nodes = n;
    b->count++;
    if(confirm == 2)
        add_search_node(id, sa, salen);
    return n;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %ecx, %ebx
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %r15
movzwl (%rsi), %esi
callq 0x3593
testq %rax, %rax
je 0x65b6
movq %rax, %r13
xorl %r12d, %r12d
movl %ebx, 0xc(%rsp)
movdqu (%r15), %xmm0
movd 0x10(%r15), %xmm1
movd 0x7bec(%rip), %xmm2     # 0xdc40
pcmpeqb 0x7bd4(%rip), %xmm0     # 0xdc30
pcmpeqb %xmm1, %xmm2
pand %xmm2, %xmm0
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x65b9
movq %r14, %rdi
callq 0x5d70
testl %eax, %eax
jne 0x65b9
movq %r14, %rdi
movl %ebp, %esi
callq 0x5dec
testl %eax, %eax
jne 0x65b9
movq %r13, %rdi
callq 0x7e4c
cmpl $0x2, %ebx
jne 0x60ad
movq 0x7b67(%rip), %rcx      # 0xdc10
movq %rcx, 0x20(%r13)
movq 0x28(%r13), %rbx
testq %rbx, %rbx
je 0x60fa
movdqu (%r15), %xmm0
movd 0x10(%r15), %xmm1
movq %rbx, %r12
movdqu (%r12), %xmm2
pcmpeqb %xmm0, %xmm2
movd 0x10(%r12), %xmm3
pcmpeqb %xmm1, %xmm3
pand %xmm2, %xmm3
pmovmskb %xmm3, %ecx
cmpl $0xffff, %ecx           # imm = 0xFFFF
je 0x636d
movq 0xc0(%r12), %r12
testq %r12, %r12
jne 0x60c4
movq %r15, 0x10(%rsp)
movl %ebp, %r15d
testl %eax, %eax
je 0x6127
cmpw $0x2, (%r14)
movq 0x7afe(%rip), %rcx      # 0xdc10
leaq 0x7b6f(%rip), %rdx      # 0xdc88
leaq 0x7b60(%rip), %rsi      # 0xdc80
cmoveq %rsi, %rdx
movq %rcx, (%rdx)
testq %rbx, %rbx
je 0x61df
movq 0x7ad9(%rip), %rbp      # 0xdc10
leaq -0xf(%rbp), %rcx
movq %rbx, %r12
cmpl $0x3, 0xb8(%r12)
jl 0x6157
cmpq %rcx, 0xb0(%r12)
jl 0x63d1
movq 0xc0(%r12), %r12
testq %r12, %r12
jne 0x613e
movl 0x18(%r13), %r12d
cmpl 0x1c(%r13), %r12d
jl 0x6517
xorl %ecx, %ecx
testq %rbx, %rbx
movl %r15d, %ebp
je 0x61f2
movq 0x7a8d(%rip), %rdx      # 0xdc10
leaq -0x1c20(%rdx), %rsi
leaq -0x384(%rdx), %rdi
addq $-0xf, %rdx
movq 0x10(%rsp), %r15
movl 0xc(%rsp), %r12d
cmpl $0x2, 0xb8(%rbx)
jg 0x61ba
cmpq %rsi, 0xa8(%rbx)
jl 0x61ba
cmpq %rdi, 0xa0(%rbx)
jge 0x61cc
movl $0x1, %ecx
cmpq %rdx, 0xb0(%rbx)
jl 0x6483
movq 0xc0(%rbx), %rbx
testq %rbx, %rbx
jne 0x619f
testl %ecx, %ecx
setne %cl
jmp 0x61fc
movl 0x18(%r13), %r12d
cmpl 0x1c(%r13), %r12d
jl 0x6517
xorl %ecx, %ecx
movl %r15d, %ebp
movq 0x10(%rsp), %r15
movl 0xc(%rsp), %r12d
testl %eax, %eax
je 0x64bf
testb %cl, %cl
jne 0x64bf
movq $0x0, 0x18(%rsp)
leaq 0x35b3(%rip), %rdi      # 0x97cf
xorl %eax, %eax
callq 0x362c
movq %r13, %rdi
leaq 0x18(%rsp), %rsi
callq 0x81b2
testl %eax, %eax
js 0x65cb
movq 0x18(%rsp), %r13
testq %r13, %r13
je 0x6346
xorl %eax, %eax
testq %rax, %rax
je 0x6255
movq %r13, %r12
movq %rax, %r13
jmp 0x6267
movq 0xc0(%r13), %r12
movq $0x0, 0xc0(%r13)
movzwl 0x18(%r13), %esi
movq %r13, %rdi
callq 0x3593
testq %rax, %rax
je 0x629a
movq %rax, %rbx
movl 0x18(%rax), %eax
cmpl 0x1c(%rbx), %eax
jge 0x62aa
movq 0x28(%rbx), %rcx
movq %rcx, 0xc0(%r13)
movq %r13, 0x28(%rbx)
incl %eax
movl %eax, 0x18(%rbx)
jmp 0x6310
leaq 0x3550(%rip), %rdi      # 0x97f1
xorl %eax, %eax
callq 0x362c
jmp 0x6308
movq %rbx, %rdi
callq 0x7e4c
testl %eax, %eax
je 0x6308
movq $0x0, 0x20(%rsp)
leaq 0x3542(%rip), %rdi      # 0x9808
xorl %eax, %eax
callq 0x362c
movq %rbx, %rdi
leaq 0x20(%rsp), %rsi
callq 0x81b2
testl %eax, %eax
js 0x6323
movq 0x20(%rsp), %rax
testq %r12, %r12
je 0x633e
testq %rax, %rax
je 0x6341
movq %r12, %rdx
movq %rdx, %rcx
movq 0xc0(%rdx), %rdx
testq %rdx, %rdx
jne 0x62f0
movq %rax, 0xc0(%rcx)
jmp 0x6341
movq %r13, %rdi
callq 0x2040
xorl %eax, %eax
movq %rax, %rcx
orq %r12, %rcx
movq %r12, %r13
jne 0x6248
jmp 0x6346
leaq 0x34f6(%rip), %rdi      # 0x9820
xorl %eax, %eax
callq 0x362c
movq %r13, %rdi
callq 0x2040
xorl %r13d, %r13d
jmp 0x6341
movq %rax, %r12
movq %r13, %rax
jmp 0x6312
movzwl (%r14), %esi
movq %r15, %rdi
callq 0x3593
movq %rax, %r13
testq %rax, %rax
movl 0xc(%rsp), %ebx
movl $0x0, %r12d
jne 0x6041
jmp 0x65b9
movl 0xc(%rsp), %ebx
testl %ebx, %ebx
je 0x6452
leaq 0x18(%r12), %rdi
movslq %ebp, %rdx
movq %r14, %rsi
callq 0x2200
movq 0x7880(%rip), %rax      # 0xdc10
movq %rax, 0xa0(%r12)
cmpl $0x2, %ebx
jl 0x65b9
movq %rax, 0xa8(%r12)
movl $0x0, 0xb8(%r12)
movq $0x0, 0xb0(%r12)
jne 0x65b9
movq %r15, %rdi
movq %r14, %rsi
movl %ebp, %edx
jmp 0x6448
movq 0x10(%rsp), %r13
movl 0x10(%r13), %eax
movl %eax, 0x10(%r12)
movdqu (%r13), %xmm0
movdqu %xmm0, (%r12)
leaq 0x18(%r12), %rdi
movslq %r15d, %rdx
movq %r14, %rsi
callq 0x2200
xorl %eax, %eax
movl 0xc(%rsp), %edx
testl %edx, %edx
movq %rbp, %rcx
cmoveq %rax, %rcx
cmpl $0x2, %edx
cmovgeq %rbp, %rax
movq %rcx, 0xa0(%r12)
movq %rax, 0xa8(%r12)
movq $0x0, 0xb0(%r12)
movl $0x0, 0xb8(%r12)
jne 0x65b9
movq %r13, %rdi
movq %r14, %rsi
movl %r15d, %edx
callq 0x813a
jmp 0x65b9
movq $-0x384, %rax           # imm = 0xFC7C
addq 0x77b0(%rip), %rax      # 0xdc10
cmpq %rax, 0xa0(%r12)
jge 0x65b9
leaq 0x18(%r12), %rdi
movslq %ebp, %rdx
movq %r14, %rsi
callq 0x2200
jmp 0x65b9
leaq 0x3326(%rip), %rdi      # 0x97b0
xorl %eax, %eax
callq 0x362c
leaq 0x18(%rsp), %rdx
movl $0x6e70, (%rdx)         # imm = 0x6E70
leaq 0x18(%rbx), %rdi
movl 0x98(%rbx), %esi
callq 0x7f00
incl 0xb8(%rbx)
movq 0x7758(%rip), %rax      # 0xdc10
movq %rax, 0xb0(%rbx)
leaq 0x30(%r13), %rdi
testl %r12d, %r12d
je 0x64f6
movslq %ebp, %rdx
movq %r14, %rsi
callq 0x2200
movl %ebp, 0xb0(%r13)
cmpl $0x2, %r12d
jne 0x65b6
movq %r15, %rdi
movq %r14, %rsi
movl %ebp, %edx
callq 0x813a
jmp 0x65b6
cmpw $0x0, (%rdi)
jne 0x65b6
movslq %ebp, %rdx
movq %r14, %rsi
callq 0x2200
movl %ebp, 0xb0(%r13)
jmp 0x65b6
movl $0x1, %edi
movl $0xc8, %esi
callq 0x21a0
testq %rax, %rax
je 0x65b6
movq %rax, %rbp
movq 0x10(%rsp), %rcx
movl 0x10(%rcx), %eax
movl %eax, 0x10(%rbp)
movdqu (%rcx), %xmm0
movdqu %xmm0, (%rbp)
movq %rbp, %rdi
addq $0x18, %rdi
movslq %r15d, %rdx
movq %r14, %rsi
callq 0x2200
movl %r15d, 0x98(%rbp)
xorl %eax, %eax
movl 0xc(%rsp), %esi
testl %esi, %esi
movq 0x76a2(%rip), %rcx      # 0xdc10
movq %rcx, %rdx
cmoveq %rax, %rdx
incl %r12d
movq %rdx, 0xa0(%rbp)
cmpl $0x2, %esi
cmovgeq %rcx, %rax
movq %rax, 0xa8(%rbp)
movq %rbx, 0xc0(%rbp)
movq %rbp, %rbx
movq %rbp, 0x28(%r13)
movl %r12d, 0x18(%r13)
jne 0x65b1
movq 0x10(%rsp), %rdi
movq %r14, %rsi
movl %r15d, %edx
callq 0x813a
movq %rbx, %r12
jmp 0x65b9
xorl %r12d, %r12d
movq %r12, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3209(%rip), %rdi      # 0x97db
xorl %r12d, %r12d
xorl %eax, %eax
callq 0x362c
jmp 0x65b9