// File: /workspace/github_c_makefile_star2_O2/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, (%rsp)
movl %edx, %r14d
movq %rsi, %rbp
movq %rdi, %r15
movzwl (%rbp), %esi
movq %r15, %rdi
callq 0x329c
testq %rax, %rax
je 0x6125
movq %rax, %r12
movq %r15, %rdi
leaq 0x7f00(%rip), %rsi      # 0xdc30
callq 0x33d2
testl %eax, %eax
je 0x6125
movq %rbp, %rdi
callq 0x5abe
testl %eax, %eax
jne 0x6125
movq %rbp, %rdi
movl %r14d, %esi
callq 0x5b5b
testl %eax, %eax
jne 0x6125
movq %r12, %rdi
callq 0x7331
movl %eax, 0x14(%rsp)
cmpl $0x2, (%rsp)
jne 0x5d7e
movq 0x7e97(%rip), %rax      # 0xdc10
movq %rax, 0x20(%r12)
leaq 0x28(%r12), %rbx
movq %rbx, %r13
movq (%r13), %r13
testq %r13, %r13
je 0x5dab
movq %r13, %rdi
movq %r15, %rsi
callq 0x33d2
testl %eax, %eax
je 0x5fa7
addq $0xc0, %r13
jmp 0x5d86
cmpl $0x0, 0x14(%rsp)
movq %rbp, 0x8(%rsp)
je 0x5dce
cmpw $0x2, (%rbp)
movq 0x7e4d(%rip), %rcx      # 0xdc10
jne 0x5dd7
movq %rcx, 0x7eb4(%rip)      # 0xdc80
jmp 0x5dde
movq 0x7e3b(%rip), %rcx      # 0xdc10
jmp 0x5dde
movq %rcx, 0x7eaa(%rip)      # 0xdc88
leaq -0xf(%rcx), %rbp
movq %rbx, %r13
movq (%r13), %r13
testq %r13, %r13
je 0x5e0e
cmpl $0x3, 0xb8(%r13)
jl 0x5e05
cmpq %rbp, 0xb0(%r13)
jl 0x602e
addq $0xc0, %r13
jmp 0x5de5
movl %r14d, 0x4(%rsp)
movl 0x18(%r12), %r14d
cmpl 0x1c(%r12), %r14d
jl 0x613a
xorl %r14d, %r14d
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x5e54
movq %rbx, %rdi
callq 0x3956
testl %eax, %eax
jne 0x5e4b
pushq $0x1
popq %r14
cmpq %rbp, 0xb0(%rbx)
jl 0x60a2
addq $0xc0, %rbx
jmp 0x5e26
cmpl $0x0, 0x14(%rsp)
je 0x60de
testl %r14d, %r14d
jne 0x60de
andq $0x0, 0x18(%rsp)
leaq 0x295a(%rip), %rdi      # 0x87cf
xorl %eax, %eax
callq 0x3324
movq %r12, %rdi
leaq 0x18(%rsp), %rsi
callq 0x767c
testl %eax, %eax
movq 0x8(%rsp), %rbp
js 0x61d3
movq 0x18(%rsp), %r12
xorl %eax, %eax
movl 0x4(%rsp), %r14d
movq %rax, %rcx
orq %r12, %rcx
je 0x5d0e
testq %rax, %rax
je 0x5ebb
movq %r12, %r13
movq %rax, %r12
jmp 0x5ecc
movq 0xc0(%r12), %r13
andq $0x0, 0xc0(%r12)
movzwl 0x18(%r12), %esi
movq %r12, %rdi
callq 0x329c
testq %rax, %rax
je 0x5f01
movq %rax, %rbx
movl 0x18(%rax), %eax
cmpl 0x1c(%rbx), %eax
jge 0x5f11
movq 0x28(%rbx), %rcx
movq %rcx, 0xc0(%r12)
movq %r12, 0x28(%rbx)
incl %eax
movl %eax, 0x18(%rbx)
jmp 0x5f74
leaq 0x28e9(%rip), %rdi      # 0x87f1
xorl %eax, %eax
callq 0x3324
jmp 0x5f6c
movq %rbx, %rdi
callq 0x7331
testl %eax, %eax
je 0x5f6c
andq $0x0, 0x20(%rsp)
leaq 0x28de(%rip), %rdi      # 0x8808
xorl %eax, %eax
callq 0x3324
movq %rbx, %rdi
leaq 0x20(%rsp), %rsi
callq 0x767c
testl %eax, %eax
js 0x5f7e
movq 0x20(%rsp), %rax
testq %r13, %r13
je 0x5f99
testq %rax, %rax
je 0x5f9c
movq %r13, %rdx
movq %rdx, %rcx
movq 0xc0(%rdx), %rdx
testq %rdx, %rdx
jne 0x5f54
movq %rax, 0xc0(%rcx)
jmp 0x5f9c
movq %r12, %rdi
callq 0x2040
movq %r13, %r12
xorl %eax, %eax
jmp 0x5ea2
leaq 0x289b(%rip), %rdi      # 0x8820
xorl %eax, %eax
callq 0x3324
movq %r12, %rdi
callq 0x2040
xorl %r12d, %r12d
jmp 0x5f9c
movq %rax, %r13
movq %r12, %rax
movq %r13, %r12
jmp 0x5ea2
movl (%rsp), %ebx
testl %ebx, %ebx
je 0x5fff
leaq 0x18(%r13), %rdi
movslq %r14d, %rdx
movq %rbp, %rsi
callq 0x2200
movq 0x7c4c(%rip), %rax      # 0xdc10
movq %rax, 0xa0(%r13)
cmpl $0x2, %ebx
jl 0x6128
andl $0x0, 0xb8(%r13)
andq $0x0, 0xb0(%r13)
movq %rax, 0xa8(%r13)
cmpl $0x2, %ebx
jne 0x6128
movq %r15, %rdi
movq %rbp, %rsi
jmp 0x6095
movq $-0x384, %rax           # imm = 0xFC7C
addq 0x7c03(%rip), %rax      # 0xdc10
cmpq %rax, 0xa0(%r13)
jge 0x6128
leaq 0x18(%r13), %rdi
movslq %r14d, %rdx
movq %rbp, %rsi
callq 0x2200
jmp 0x6128
movl 0x10(%r15), %eax
movl %eax, 0x10(%r13)
movups (%r15), %xmm0
movups %xmm0, (%r13)
leaq 0x18(%r13), %rdi
movslq %r14d, %rdx
movq 0x8(%rsp), %rbx
movq %rbx, %rsi
movq %rcx, %r12
callq 0x2200
xorl %eax, %eax
movl (%rsp), %edx
testl %edx, %edx
movq %r12, %rcx
cmoveq %rax, %rcx
andq $0x0, 0xb0(%r13)
andl $0x0, 0xb8(%r13)
movq %rcx, 0xa0(%r13)
cmpl $0x2, %edx
cmovgeq %r12, %rax
movq %rax, 0xa8(%r13)
jne 0x6128
movq %r15, %rdi
movq %rbx, %rsi
movl %r14d, %edx
callq 0x7607
jmp 0x6128
leaq 0x2707(%rip), %rdi      # 0x87b0
xorl %eax, %eax
callq 0x3324
leaq 0x18(%rsp), %rdx
movl $0x6e70, (%rdx)         # imm = 0x6E70
leaq 0x18(%rbx), %rdi
movl 0x98(%rbx), %esi
callq 0x73d7
incl 0xb8(%rbx)
movq 0x7b39(%rip), %rax      # 0xdc10
movq %rax, 0xb0(%rbx)
movl (%rsp), %ebp
testl %ebp, %ebp
movq 0x8(%rsp), %r14
je 0x611c
movq %r12, %rdi
addq $0x30, %rdi
movl 0x4(%rsp), %ebx
movslq %ebx, %rdx
movq %r14, %rsi
callq 0x2200
movl %ebx, 0xb0(%r12)
cmpl $0x2, %ebp
jne 0x6125
movq %r15, %rdi
movq %r14, %rsi
movl %ebx, %edx
callq 0x7607
jmp 0x6125
cmpw $0x0, 0x30(%r12)
je 0x60ea
xorl %r13d, %r13d
movq %r13, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rcx, %rbp
pushq $0x1
popq %rdi
movl $0xc8, %esi
callq 0x21a0
testq %rax, %rax
je 0x6125
movq %rax, %r13
movl 0x10(%r15), %eax
movl %eax, 0x10(%r13)
movups (%r15), %xmm0
movups %xmm0, (%r13)
movq %r13, %rdi
addq $0x18, %rdi
movl 0x4(%rsp), %ebx
movslq %ebx, %rdx
movq 0x8(%rsp), %rsi
callq 0x2200
xorl %eax, %eax
movl (%rsp), %edx
testl %edx, %edx
movq %rbp, %rcx
cmoveq %rax, %rcx
incl %r14d
movl %ebx, 0x98(%r13)
movq %rcx, 0xa0(%r13)
cmpl $0x2, %edx
cmovgeq %rbp, %rax
movq %rax, 0xa8(%r13)
movq 0x28(%r12), %rax
movq %rax, 0xc0(%r13)
movq %r13, 0x28(%r12)
movl %r14d, 0x18(%r12)
jne 0x6128
movq %r15, %rdi
movq 0x8(%rsp), %rsi
movl %ebx, %edx
jmp 0x6098
leaq 0x2601(%rip), %rdi      # 0x87db
xorl %r13d, %r13d
xorl %eax, %eax
callq 0x3324
jmp 0x6128