// File: /workspace/github_c_makefile_star2_O1/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, 0xc(%rsp)
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %r15
movq %rdi, 0x18(%rsp)
movzwl (%r14), %esi
movq %r15, %rdi
callq 0x35d4
testq %rax, %rax
je 0x65d0
movq %rax, %r13
movdqu (%r15), %xmm0
movd 0x10(%r15), %xmm1
movd 0x7b77(%rip), %xmm2     # 0xdc40
pcmpeqb 0x7b5f(%rip), %xmm0     # 0xdc30
pcmpeqb %xmm1, %xmm2
pand %xmm2, %xmm0
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x65d0
movq %r14, %rdi
callq 0x5de1
testl %eax, %eax
jne 0x65d0
movq %r14, %rdi
movl %ebp, %esi
callq 0x5e5d
testl %eax, %eax
jne 0x65d0
movq %r13, %rdi
callq 0x7e61
movl %eax, %r15d
cmpl $0x2, 0xc(%rsp)
jne 0x6127
movq 0x7aed(%rip), %rax      # 0xdc10
movq %rax, 0x20(%r13)
movq 0x28(%r13), %r12
testq %r12, %r12
je 0x6173
movq 0x18(%rsp), %rax
movdqu (%rax), %xmm0
movd 0x10(%rax), %xmm1
movdqu (%r12), %xmm2
pcmpeqb %xmm0, %xmm2
movd 0x10(%r12), %xmm3
pcmpeqb %xmm1, %xmm3
pand %xmm2, %xmm3
pmovmskb %xmm3, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x6412
movq 0xc0(%r12), %r12
testq %r12, %r12
jne 0x613e
movq %r14, %rbx
movl %ebp, %r14d
testl %r15d, %r15d
je 0x619e
cmpw $0x2, (%rbx)
movq 0x7a87(%rip), %rax      # 0xdc10
leaq 0x7af8(%rip), %rcx      # 0xdc88
leaq 0x7ae9(%rip), %rdx      # 0xdc80
cmoveq %rdx, %rcx
movq %rax, (%rcx)
movq 0x28(%r13), %r12
testq %r12, %r12
je 0x61d8
movq 0x7a62(%rip), %rbp      # 0xdc10
leaq -0xf(%rbp), %rax
cmpl $0x3, 0xb8(%r12)
jl 0x61cb
cmpq %rax, 0xb0(%r12)
jl 0x6446
movq 0xc0(%r12), %r12
testq %r12, %r12
jne 0x61b2
movl 0x18(%r13), %eax
cmpl 0x1c(%r13), %eax
jl 0x6530
movq 0x28(%r13), %r12
xorl %eax, %eax
testq %r12, %r12
movl %r14d, %ebp
je 0x6252
movq 0x7a15(%rip), %rcx      # 0xdc10
leaq -0x1c20(%rcx), %rdx
leaq -0x384(%rcx), %rsi
addq $-0xf, %rcx
movq %rbx, %r14
cmpl $0x2, 0xb8(%r12)
jg 0x622f
cmpq %rdx, 0xa8(%r12)
jl 0x622f
cmpq %rsi, 0xa0(%r12)
jge 0x623e
movl $0x1, %eax
cmpq %rcx, 0xb0(%r12)
jl 0x6257
movq 0xc0(%r12), %r12
testq %r12, %r12
jne 0x6210
testl %eax, %eax
setne %al
jmp 0x629d
movq %rbx, %r14
jmp 0x629d
leaq 0x3562(%rip), %rdi      # 0x97c0
xorl %eax, %eax
callq 0x366b
movl $0x6e70, 0x10(%rsp)     # imm = 0x6E70
leaq 0x18(%r12), %rdi
movl 0x98(%r12), %esi
leaq 0x10(%rsp), %rdx
callq 0x7f15
incl 0xb8(%r12)
movq 0x797d(%rip), %rax      # 0xdc10
movq %rax, 0xb0(%r12)
movb $0x1, %al
testl %r15d, %r15d
je 0x65e5
testb %al, %al
jne 0x65e5
movq $0x0, 0x10(%rsp)
leaq 0x3521(%rip), %rdi      # 0x97df
xorl %eax, %eax
callq 0x366b
movq %r13, %rdi
leaq 0x10(%rsp), %rsi
callq 0x81c8
movl %eax, %r12d
testl %eax, %eax
movq 0x18(%rsp), %r15
js 0x63f6
movq 0x10(%rsp), %rax
testq %rax, %rax
je 0x6404
xorl %r13d, %r13d
testq %r13, %r13
jne 0x6312
movq 0xc0(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq $0x0, 0xc0(%rax)
movq %rax, %r13
movzwl 0x18(%r13), %esi
movq %r13, %rdi
callq 0x35d4
testq %rax, %rax
je 0x6342
movl 0x18(%rax), %edx
movb $0x1, %cl
cmpl 0x1c(%rax), %edx
jge 0x6348
movq 0x28(%rax), %rcx
movq %rcx, 0xc0(%r13)
movq %r13, 0x28(%rax)
incl %edx
movl %edx, 0x18(%rax)
xorl %ebx, %ebx
xorl %ecx, %ecx
jmp 0x634b
movq %rax, %rbx
testq %rax, %rax
je 0x63b7
testb %cl, %cl
je 0x63cd
movq %rbx, %rdi
callq 0x7e61
testl %eax, %eax
je 0x63c5
movq $0x0, 0x20(%rsp)
leaq 0x34a8(%rip), %rdi      # 0x9818
xorl %eax, %eax
callq 0x366b
movq %rbx, %rdi
leaq 0x20(%rsp), %rsi
callq 0x81c8
testl %eax, %eax
js 0x63e3
movq 0x10(%rsp), %rax
movq 0x20(%rsp), %rcx
testq %rax, %rax
je 0x63ec
testq %rcx, %rcx
je 0x63ef
movq %rax, %rsi
movq %rsi, %rdx
movq 0xc0(%rsi), %rsi
testq %rsi, %rsi
jne 0x639f
movq %rcx, 0xc0(%rdx)
jmp 0x63ef
leaq 0x3443(%rip), %rdi      # 0x9801
xorl %eax, %eax
callq 0x366b
movq %r13, %rdi
callq 0x2040
xorl %r13d, %r13d
movq 0x10(%rsp), %rax
movq %rax, %rcx
orq %r13, %rcx
jne 0x62f3
jmp 0x6404
leaq 0x3446(%rip), %rdi      # 0x9830
jmp 0x63be
movq %rcx, %rax
movq %rax, 0x10(%rsp)
jmp 0x63d0
leaq 0x33ee(%rip), %rdi      # 0x97eb
xorl %eax, %eax
callq 0x366b
testl %r12d, %r12d
jns 0x609e
jmp 0x65d0
cmpl $0x0, 0xc(%rsp)
je 0x64b8
leaq 0x18(%r12), %rdi
movslq %ebp, %rdx
movq %r14, %rsi
callq 0x2200
movq 0x77dc(%rip), %rax      # 0xdc10
movq %rax, 0xa0(%r12)
movq 0x18(%rsp), %r15
jmp 0x64e5
movq 0x18(%rsp), %r15
movl 0x10(%r15), %eax
movl %eax, 0x10(%r12)
movups (%r15), %xmm0
movups %xmm0, (%r12)
leaq 0x18(%r12), %rdi
movslq %r14d, %rdx
movq %rbx, %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
movl %r14d, %ebp
movq %rbx, %r14
movq %rcx, 0xa0(%r12)
movq %rax, 0xa8(%r12)
movq $0x0, 0xb0(%r12)
movl $0x0, 0xb8(%r12)
je 0x651e
jmp 0x65d3
movq $-0x384, %rax           # imm = 0xFC7C
addq 0x774a(%rip), %rax      # 0xdc10
cmpq %rax, 0xa0(%r12)
movq 0x18(%rsp), %r15
jge 0x6513
leaq 0x18(%r12), %rdi
movslq %ebp, %rdx
movq %r14, %rsi
callq 0x2200
cmpl $0x2, 0xc(%rsp)
jl 0x6513
movq 0x771d(%rip), %rax      # 0xdc10
movq %rax, 0xa8(%r12)
movl $0x0, 0xb8(%r12)
movq $0x0, 0xb0(%r12)
cmpl $0x2, 0xc(%rsp)
jne 0x65d3
movq %r15, %rdi
movq %r14, %rsi
movl %ebp, %edx
callq 0x8150
jmp 0x65d3
movl $0x1, %edi
movl $0xc8, %esi
callq 0x21a0
testq %rax, %rax
je 0x65d0
movq %rax, %r12
movl %r14d, %ebp
movq 0x18(%rsp), %r15
movl 0x10(%r15), %eax
movl %eax, 0x10(%r12)
movdqu (%r15), %xmm0
movdqu %xmm0, (%r12)
movq %r12, %rdi
addq $0x18, %rdi
movslq %r14d, %rdx
movq %rbx, %r14
movq %rbx, %rsi
callq 0x2200
movl %ebp, 0x98(%r12)
xorl %eax, %eax
movl 0xc(%rsp), %esi
testl %esi, %esi
movq 0x767d(%rip), %rcx      # 0xdc10
movq %rcx, %rdx
cmoveq %rax, %rdx
cmpl $0x2, %esi
movq %rdx, 0xa0(%r12)
cmovgeq %rcx, %rax
movq %rax, 0xa8(%r12)
movq 0x28(%r13), %rax
movq %rax, 0xc0(%r12)
incl 0x18(%r13)
movq %r12, 0x28(%r13)
cmpl $0x2, %esi
je 0x651e
jmp 0x65d3
xorl %r12d, %r12d
movq %r12, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x0, 0xc(%rsp)
movq 0x18(%rsp), %r15
je 0x660c
movq %r13, %rdi
addq $0x30, %rdi
movslq %ebp, %rdx
movq %r14, %rsi
callq 0x2200
movl %ebp, 0xb0(%r13)
jmp 0x6614
cmpw $0x0, 0x30(%r13)
je 0x65f1
xorl %r12d, %r12d
jmp 0x6513