示例#1
0
static void listener_next_job_handler (BListener *o)
{
    DebugObject_Access(&o->d_obj);
    ASSERT(!o->busy)
    
    // free ready socket
    if (o->ready) {
        BLog(BLOG_ERROR, "discarding connection");
        
        // close new socket
        if (closesocket(o->newsock) == SOCKET_ERROR) {
            BLog(BLOG_ERROR, "closesocket failed");
        }
        
        // set not ready
        o->ready = 0;
    }
    
    // create new socket
    if ((o->newsock = WSASocket(o->sys_family, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) {
        BLog(BLOG_ERROR, "WSASocket failed");
        goto fail0;
    }
    
    // start accept operation
    while (1) {
        memset(&o->olap.olap, 0, sizeof(o->olap.olap));
        DWORD bytes;
        BOOL res = o->fnAcceptEx(o->sock, o->newsock, o->addrbuf, 0, sizeof(struct BListener_addrbuf_stub), sizeof(struct BListener_addrbuf_stub), &bytes, &o->olap.olap);
        if (res == FALSE && WSAGetLastError() != ERROR_IO_PENDING) {
            BLog(BLOG_ERROR, "AcceptEx failed");
            continue;
        }
        break;
    }
    
    // set busy
    o->busy = 1;
    
    return;
    
fail0:
    return;
}
示例#2
0
static void input_handler_send (PacketPassFifoQueueFlow *o, uint8_t *data, int data_len)
{
    PacketPassFifoQueue *queue = o->queue;
    DebugObject_Access(&o->d_obj);
    ASSERT(!o->is_waiting)
    ASSERT(o != queue->sending_flow)
    ASSERT(!queue->freeing)
    
    // queue flow
    o->waiting_data = data;
    o->waiting_len = data_len;
    LinkedList1_Append(&queue->waiting_flows_list, &o->waiting_flows_list_node);
    o->is_waiting = 1;
    
    // schedule
    if (!queue->sending_flow && !BPending_IsSet(&queue->schedule_job)) {
        schedule(queue);
    }
}
示例#3
0
int BufferWriter_StartPacket (BufferWriter *o, uint8_t **buf)
{
    ASSERT(!o->d_writing)
    DebugObject_Access(&o->d_obj);
    
    if (!o->out_have) {
        return 0;
    }
    
    if (buf) {
        *buf = o->out;
    }
    
    #ifndef NDEBUG
    o->d_writing = 1;
    #endif
    
    return 1;
}
示例#4
0
void OTPGenerator_SetSeed (OTPGenerator *g, uint8_t *key, uint8_t *iv)
{
    DebugObject_Access(&g->d_obj);

    // free existing work
    if (g->tw_have) {
        BThreadWork_Free(&g->tw);
    }

    // copy key and IV
    memcpy(g->tw_key, key, BEncryption_cipher_key_size(g->cipher));
    memcpy(g->tw_iv, iv, BEncryption_cipher_block_size(g->cipher));

    // start work
    BThreadWork_Init(&g->tw, g->twd, (BThreadWork_handler_done)work_done_handler, g, (BThreadWork_work_func)work_func, g);

    // set have work
    g->tw_have = 1;
}
示例#5
0
void BPendingGroup_ExecuteJob (BPendingGroup *g)
{
    ASSERT(!LinkedList1_IsEmpty(&g->jobs))
    DebugObject_Access(&g->d_obj);
    
    // get a job
    LinkedList1Node *node = LinkedList1_GetLast(&g->jobs);
    BPending *p = UPPER_OBJECT(node, BPending, pending_node);
    ASSERT(p->pending)
    
    // remove from jobs list
    LinkedList1_Remove(&g->jobs, &p->pending_node);
    
    // set not pending
    p->pending = 0;
    
    // execute job
    p->handler(p->user);
    return;
}
示例#6
0
void PacketPassFifoQueueFlow_Init (PacketPassFifoQueueFlow *o, PacketPassFifoQueue *queue)
{
    DebugObject_Access(&queue->d_obj);
    ASSERT(!queue->freeing)
    
    // init arguments
    o->queue = queue;
    
    // init input
    PacketPassInterface_Init(&o->input, PacketPassInterface_GetMTU(queue->output), (PacketPassInterface_handler_send)input_handler_send, o, queue->pg);
    
    // set not waiting
    o->is_waiting = 0;
    
    // set no busy handler
    o->handler_busy = NULL;
    
    DebugCounter_Increment(&queue->d_flows_ctr);
    DebugObject_Init(&o->d_obj);
}
示例#7
0
int OTPChecker_CheckOTP (OTPChecker *mc, uint16_t seed_id, otp_t otp)
{
    DebugObject_Access(&mc->d_obj);
    
    // try tables in reverse order
    for (int i = 1; i <= mc->tables_used; i++) {
        int table_index = bmodadd_int(mc->next_table, mc->num_tables - i, mc->num_tables);
        if (table_index == mc->next_table && mc->tw_have) {
            // ignore table that is being generated
            continue;
        }
        
        struct OTPChecker_table *table = &mc->tables[table_index];
        if (table->id == seed_id) {
            return OTPChecker_Table_CheckOTP(mc, table, otp);
        }
    }
    
    return 0;
}
示例#8
0
void output_handler_done (PacketBuffer *buf)
{
    DebugObject_Access(&buf->d_obj);
    
    // remember if buffer is full
    int was_full = (buf->buf.input_avail < buf->input_mtu);
    
    // remove packet from buffer
    ChunkBuffer2_ConsumePacket(&buf->buf);
    
    // if buffer was full and there is space, schedule receive
    if (was_full && buf->buf.input_avail >= buf->input_mtu) {
        PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest);
    }
    
    // if there is more data, schedule send
    if (buf->buf.output_avail >= 0) {
        PacketPassInterface_Sender_Send(buf->output, buf->buf.output_dest, buf->buf.output_avail);
    }
}
示例#9
0
static void connector_olap_handler (BConnector *o, int event, DWORD bytes)
{
    DebugObject_Access(&o->d_obj);
    ASSERT(o->sock != INVALID_SOCKET)
    ASSERT(o->busy)
    ASSERT(!o->ready)
    ASSERT(event == BREACTOR_IOCP_EVENT_SUCCEEDED || event == BREACTOR_IOCP_EVENT_FAILED)
    
    // set not busy
    o->busy = 0;
    
    if (event == BREACTOR_IOCP_EVENT_FAILED) {
        BLog(BLOG_ERROR, "connection failed");
    } else {
        // set ready
        o->ready = 1;
    }
    
    // call handler
    o->handler(o->user, !o->ready);
    return;
}
示例#10
0
void input_handler_done (PacketBuffer *buf, int in_len)
{
    ASSERT(in_len >= 0)
    ASSERT(in_len <= buf->input_mtu)
    DebugObject_Access(&buf->d_obj);
    
    // remember if buffer is empty
    int was_empty = (buf->buf.output_avail < 0);
    
    // submit packet to buffer
    ChunkBuffer2_SubmitPacket(&buf->buf, in_len);
    
    // if there is space, schedule receive
    if (buf->buf.input_avail >= buf->input_mtu) {
        PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest);
    }
    
    // if buffer was empty, schedule send
    if (was_empty) {
        PacketPassInterface_Sender_Send(buf->output, buf->buf.output_dest, buf->buf.output_avail);
    }
}
示例#11
0
static void work_done_handler (OTPChecker *mc)
{
    ASSERT(mc->tw_have)
    DebugObject_Access(&mc->d_obj);
    
    // free work
    BThreadWork_Free(&mc->tw);
    mc->tw_have = 0;
    
    // update next table number
    mc->next_table = bmodadd_int(mc->next_table, 1, mc->num_tables);
    
    // update number of used tables if not all are used yet
    if (mc->tables_used < mc->num_tables) {
        mc->tables_used++;
    }
    
    // call handler
    if (mc->handler) {
        mc->handler(mc->user);
        return;
    }
}
示例#12
0
void OTPChecker_AddSeed (OTPChecker *mc, uint16_t seed_id, uint8_t *key, uint8_t *iv)
{
    ASSERT(mc->next_table >= 0)
    ASSERT(mc->next_table < mc->num_tables)
    DebugObject_Access(&mc->d_obj);
    
    // free existing work
    if (mc->tw_have) {
        BThreadWork_Free(&mc->tw);
    }
    
    // set table's seed ID
    mc->tables[mc->next_table].id = seed_id;
    
    // copy key and IV
    memcpy(mc->tw_key, key, BEncryption_cipher_key_size(mc->cipher));
    memcpy(mc->tw_iv, iv, BEncryption_cipher_block_size(mc->cipher));
    
    // start work
    BThreadWork_Init(&mc->tw, mc->twd, (BThreadWork_handler_done)work_done_handler, mc, (BThreadWork_work_func)work_func, mc);
    
    // set have work
    mc->tw_have = 1;
}
示例#13
0
static void receiver_recv_handler_send (DPReceiveReceiver *o, uint8_t *packet, int packet_len)
{
    DebugObject_Access(&o->d_obj);
    DPReceivePeer *peer = o->peer;
    DPReceiveDevice *device = peer->device;
    ASSERT(packet_len >= 0)
    ASSERT(packet_len <= device->packet_mtu)
    
    uint8_t *data = packet;
    int data_len = packet_len;
    
    int local = 0;
    DPReceivePeer *src_peer;
    DPReceivePeer *relay_dest_peer = NULL;
    
    // check header
    if (data_len < sizeof(struct dataproto_header)) {
        BLog(BLOG_WARNING, "no dataproto header");
        goto out;
    }
    struct dataproto_header header;
    memcpy(&header, data, sizeof(header));
    data += sizeof(header);
    data_len -= sizeof(header);
    uint8_t flags = ltoh8(header.flags);
    peerid_t from_id = ltoh16(header.from_id);
    int num_ids = ltoh16(header.num_peer_ids);
    
    // check destination ID
    if (!(num_ids == 0 || num_ids == 1)) {
        BLog(BLOG_WARNING, "wrong number of destinations");
        goto out;
    }
    peerid_t to_id = 0; // to remove warning
    if (num_ids == 1) {
        if (data_len < sizeof(struct dataproto_peer_id)) {
            BLog(BLOG_WARNING, "missing destination");
            goto out;
        }
        struct dataproto_peer_id id;
        memcpy(&id, data, sizeof(id));
        to_id = ltoh16(id.id);
        data += sizeof(id);
        data_len -= sizeof(id);
    }
    
    // check remaining data
    if (data_len > device->device_mtu) {
        BLog(BLOG_WARNING, "frame too large");
        goto out;
    }
    
    // inform sink of received packet
    if (peer->dp_sink) {
        DataProtoSink_Received(peer->dp_sink, !!(flags & DATAPROTO_FLAGS_RECEIVING_KEEPALIVES));
    }
    
    if (num_ids == 1) {
        // find source peer
        if (!(src_peer = find_peer(device, from_id))) {
            BLog(BLOG_INFO, "source peer %d not known", (int)from_id);
            goto out;
        }
        
        // is frame for device or another peer?
        if (device->have_peer_id && to_id == device->peer_id) {
            // let the frame decider analyze the frame
            FrameDeciderPeer_Analyze(src_peer->decider_peer, data, data_len);
            
            // pass frame to device
            local = 1;
        } else {
            // check if relaying is allowed
            if (!peer->is_relay_client) {
                BLog(BLOG_WARNING, "relaying not allowed");
                goto out;
            }
            
            // provided source ID must be the peer sending the frame
            if (src_peer != peer) {
                BLog(BLOG_WARNING, "relay source must be the sending peer");
                goto out;
            }
            
            // find destination peer
            DPReceivePeer *dest_peer = find_peer(device, to_id);
            if (!dest_peer) {
                BLog(BLOG_INFO, "relay destination peer not known");
                goto out;
            }
            
            // destination cannot be source
            if (dest_peer == src_peer) {
                BLog(BLOG_WARNING, "relay destination cannot be the source");
                goto out;
            }
            
            relay_dest_peer = dest_peer;
        }
    }
    
out:
    // accept packet
    PacketPassInterface_Done(&o->recv_if);
    
    // pass packet to device
    if (local) {
        o->device->output_func(o->device->output_func_user, data, data_len);
    }
    
    // relay frame
    if (relay_dest_peer) {
        DPRelayRouter_SubmitFrame(&device->relay_router, &src_peer->relay_source, &relay_dest_peer->relay_sink, data, data_len, device->relay_flow_buffer_size, device->relay_flow_inactivity_time);
    }
}
示例#14
0
PacketPassInterface * DPReceiveReceiver_GetInput (DPReceiveReceiver *o)
{
    DebugObject_Access(&o->d_obj);
    
    return &o->recv_if;
}
示例#15
0
PacketPassInterface * PacketPassFifoQueueFlow_GetInput (PacketPassFifoQueueFlow *o)
{
    DebugObject_Access(&o->d_obj);
    
    return &o->input;
}
示例#16
0
void NCDUdevMonitor_AssertReady (NCDUdevMonitor *o)
{
    DebugObject_Access(&o->d_obj);
    DebugError_AssertNoError(&o->d_err);
    NCDUdevMonitorParser_AssertReady(&o->parser);
}
示例#17
0
void send_handler_done (BSocksClient *o)
{
    DebugObject_Access(&o->d_obj);
    ASSERT(o->buffer)
    
    switch (o->state) {
        case STATE_SENDING_HELLO: {
            BLog(BLOG_DEBUG, "sent hello");
            
            // allocate buffer for receiving hello
            bsize_t size = bsize_fromsize(sizeof(struct socks_server_hello));
            if (!reserve_buffer(o, size)) {
                goto fail;
            }
            
            // receive hello
            start_receive(o, (uint8_t *)o->buffer, size.value);
            
            // set state
            o->state = STATE_SENT_HELLO;
        } break;
        
        case STATE_SENDING_REQUEST: {
            BLog(BLOG_DEBUG, "sent request");
            
            // allocate buffer for receiving reply
            bsize_t size = bsize_add(
                bsize_fromsize(sizeof(struct socks_reply_header)),
                bsize_max(bsize_fromsize(sizeof(struct socks_addr_ipv4)), bsize_fromsize(sizeof(struct socks_addr_ipv6)))
            );
            if (!reserve_buffer(o, size)) {
                goto fail;
            }
            
            // receive reply header
            start_receive(o, (uint8_t *)o->buffer, sizeof(struct socks_reply_header));
            
            // set state
            o->state = STATE_SENT_REQUEST;
        } break;
        
        case STATE_SENDING_PASSWORD: {
            BLog(BLOG_DEBUG, "send password");
            
            // allocate buffer for receiving reply
            bsize_t size = bsize_fromsize(2);
            if (!reserve_buffer(o, size)) {
                goto fail;
            }
            
            // receive reply header
            start_receive(o, (uint8_t *)o->buffer, size.value);
            
            // set state
            o->state = STATE_SENT_PASSWORD;
        } break;
        
        default:
            ASSERT(0);
    }
    
    return;
    
fail:
    report_error(o, BSOCKSCLIENT_EVENT_ERROR);
}
示例#18
0
void connector_handler (BSocksClient* o, int is_error)
{
    DebugObject_Access(&o->d_obj);
    ASSERT(o->state == STATE_CONNECTING)
    
    // check connection result
    if (is_error) {
        // PSIPHON
        // BLog(BLOG_ERROR, "connection failed");
        BLog(BLOG_WARNING, "connection failed");
        goto fail0;
    }
    
    // init connection
    if (!BConnection_Init(&o->con, BConnection_source_connector(&o->connector), o->reactor, o, (BConnection_handler)connection_handler)) {
        BLog(BLOG_ERROR, "BConnection_Init failed");
        goto fail0;
    }
    
    BLog(BLOG_DEBUG, "connected");
    
    // init control I/O
    init_control_io(o);
    
    // check number of methods
    if (o->num_auth_info == 0 || o->num_auth_info > 255) {
        BLog(BLOG_ERROR, "invalid number of authentication methods");
        goto fail1;
    }
    
    // allocate buffer for sending hello
    bsize_t size = bsize_add(
        bsize_fromsize(sizeof(struct socks_client_hello_header)), 
        bsize_mul(
            bsize_fromsize(o->num_auth_info),
            bsize_fromsize(sizeof(struct socks_client_hello_method))
        )
    );
    if (!reserve_buffer(o, size)) {
        goto fail1;
    }
    
    // write hello header
    struct socks_client_hello_header header;
    header.ver = hton8(SOCKS_VERSION);
    header.nmethods = hton8(o->num_auth_info);
    memcpy(o->buffer, &header, sizeof(header));
    
    // write hello methods
    for (size_t i = 0; i < o->num_auth_info; i++) {
        struct socks_client_hello_method method;
        method.method = hton8(o->auth_info[i].auth_type);
        memcpy(o->buffer + sizeof(header) + i * sizeof(method), &method, sizeof(method));
    }
    
    // send
    PacketPassInterface_Sender_Send(o->control.send_if, (uint8_t *)o->buffer, size.value);
    
    // set state
    o->state = STATE_SENDING_HELLO;
    
    return;
    
fail1:
    free_control_io(o);
    BConnection_Free(&o->con);
fail0:
    report_error(o, BSOCKSCLIENT_EVENT_ERROR);
    return;
}
示例#19
0
static void output_handler_done (SinglePacketBuffer *o)
{
    DebugObject_Access(&o->d_obj);
    
    PacketRecvInterface_Receiver_Recv(o->input, o->buf);
}
示例#20
0
int BPending_IsSet (BPending *o)
{
    DebugObject_Access(&o->d_obj);
    
    return o->pending;
}
示例#21
0
BufferWriter * PacketProtoFlow_GetInput (PacketProtoFlow *o)
{
    DebugObject_Access(&o->d_obj);
    
    return &o->ainput;
}
示例#22
0
int OTPGenerator_GetPosition (OTPGenerator *g)
{
    DebugObject_Access(&g->d_obj);

    return g->position;
}
示例#23
0
static void recv_if_handler_done (BArpProbe *o, int data_len)
{
    DebugObject_Access(&o->d_obj);
    ASSERT(data_len >= 0)
    ASSERT(data_len <= sizeof(struct arp_packet))
    
    // receive next packet
    PacketRecvInterface_Receiver_Recv(o->recv_if, (uint8_t *)&o->recv_packet);
    
    if (data_len != sizeof(struct arp_packet)) {
        BLog(BLOG_WARNING, "receive: wrong size");
        return;
    }
    
    struct arp_packet *arp = &o->recv_packet;
    
    if (ntoh16(arp->hardware_type) != ARP_HARDWARE_TYPE_ETHERNET) {
        BLog(BLOG_WARNING, "receive: wrong hardware type");
        return;
    }
    
    if (ntoh16(arp->protocol_type) != ETHERTYPE_IPV4) {
        BLog(BLOG_WARNING, "receive: wrong protocol type");
        return;
    }
    
    if (ntoh8(arp->hardware_size) != 6) {
        BLog(BLOG_WARNING, "receive: wrong hardware size");
        return;
    }
    
    if (ntoh8(arp->protocol_size) != 4) {
        BLog(BLOG_WARNING, "receive: wrong protocol size");
        return;
    }
    
    if (ntoh16(arp->opcode) != ARP_OPCODE_REPLY) {
        return;
    }
    
    if (arp->sender_ip != o->addr) {
        return;
    }
    
    int old_state = o->state;
    
    // set minus one missed
    o->num_missed = -1;
    
    // set timer
    BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_WAITSEND);
    
    // set state exist
    o->state = STATE_EXIST;
    
    // report exist if needed
    if (old_state == STATE_INITIAL || old_state == STATE_NOEXIST) {
        o->handler(o->user, BARPPROBE_EVENT_EXIST);
        return;
    }
}
示例#24
0
PacketRecvInterface * BufferWriter_GetOutput (BufferWriter *o)
{
    DebugObject_Access(&o->d_obj);
    
    return &o->recv_interface;
}
示例#25
0
void connector_handler (ServerConnection *o, int is_error)
{
    DebugObject_Access(&o->d_obj);
    ASSERT(o->state == STATE_CONNECTING)
    ASSERT(!o->buffers_released)
    
    // check connection attempt result
    if (is_error) {
        BLog(BLOG_ERROR, "connection failed");
        goto fail0;
    }
    
    BLog(BLOG_NOTICE, "connected");
    
    // init connection
    if (!BConnection_Init(&o->con, BConnection_source_connector(&o->connector), o->reactor, o, (BConnection_handler)connection_handler)) {
        BLog(BLOG_ERROR, "BConnection_Init failed");
        goto fail0;
    }
    
    // init connection interfaces
    BConnection_SendAsync_Init(&o->con);
    BConnection_RecvAsync_Init(&o->con);
    
    StreamPassInterface *send_iface = BConnection_SendAsync_GetIf(&o->con);
    StreamRecvInterface *recv_iface = BConnection_RecvAsync_GetIf(&o->con);
    
    if (o->have_ssl) {
        // create bottom NSPR file descriptor
        if (!BSSLConnection_MakeBackend(&o->bottom_prfd, send_iface, recv_iface, o->twd, o->ssl_flags)) {
            BLog(BLOG_ERROR, "BSSLConnection_MakeBackend failed");
            goto fail0a;
        }
        
        // create SSL file descriptor from the bottom NSPR file descriptor
        if (!(o->ssl_prfd = SSL_ImportFD(NULL, &o->bottom_prfd))) {
            BLog(BLOG_ERROR, "SSL_ImportFD failed");
            ASSERT_FORCE(PR_Close(&o->bottom_prfd) == PR_SUCCESS)
            goto fail0a;
        }
        
        // set client mode
        if (SSL_ResetHandshake(o->ssl_prfd, PR_FALSE) != SECSuccess) {
            BLog(BLOG_ERROR, "SSL_ResetHandshake failed");
            goto fail1;
        }
        
        // set server name
        if (SSL_SetURL(o->ssl_prfd, o->server_name) != SECSuccess) {
            BLog(BLOG_ERROR, "SSL_SetURL failed");
            goto fail1;
        }
        
        // set client certificate callback
        if (SSL_GetClientAuthDataHook(o->ssl_prfd, (SSLGetClientAuthData)client_auth_data_callback, o) != SECSuccess) {
            BLog(BLOG_ERROR, "SSL_GetClientAuthDataHook failed");
            goto fail1;
        }
        
        // init BSSLConnection
        BSSLConnection_Init(&o->sslcon, o->ssl_prfd, 0, BReactor_PendingGroup(o->reactor), o, (BSSLConnection_handler)sslcon_handler);
        
        send_iface = BSSLConnection_GetSendIf(&o->sslcon);
        recv_iface = BSSLConnection_GetRecvIf(&o->sslcon);
    }
示例#26
0
PacketRecvInterface * SCOutmsgEncoder_GetOutput (SCOutmsgEncoder *o)
{
    DebugObject_Access(&o->d_obj);
    
    return &o->output;
}
示例#27
0
void recv_handler_done (BSocksClient *o, int data_len)
{
    ASSERT(data_len >= 0)
    ASSERT(data_len <= o->control.recv_total - o->control.recv_len)
    DebugObject_Access(&o->d_obj);
    
    o->control.recv_len += data_len;
    
    if (o->control.recv_len < o->control.recv_total) {
        do_receive(o);
        return;
    }
    
    switch (o->state) {
        case STATE_SENT_HELLO: {
            BLog(BLOG_DEBUG, "received hello");
            
            struct socks_server_hello imsg;
            memcpy(&imsg, o->buffer, sizeof(imsg));
            
            if (ntoh8(imsg.ver) != SOCKS_VERSION) {
                BLog(BLOG_NOTICE, "wrong version");
                goto fail;
            }
            
            size_t auth_index;
            for (auth_index = 0; auth_index < o->num_auth_info; auth_index++) {
                if (o->auth_info[auth_index].auth_type == ntoh8(imsg.method)) {
                    break;
                }
            }
            
            if (auth_index == o->num_auth_info) {
                BLog(BLOG_NOTICE, "server didn't accept any authentication method");
                goto fail;
            }
            
            const struct BSocksClient_auth_info *ai = &o->auth_info[auth_index];
            
            switch (ai->auth_type) {
                case SOCKS_METHOD_NO_AUTHENTICATION_REQUIRED: {
                    BLog(BLOG_DEBUG, "no authentication");
                    
                    auth_finished(o);
                } break;
                
                case SOCKS_METHOD_USERNAME_PASSWORD: {
                    BLog(BLOG_DEBUG, "password authentication");
                    
                    if (ai->password.username_len == 0 || ai->password.username_len > 255 ||
                        ai->password.password_len == 0 || ai->password.password_len > 255
                    ) {
                        BLog(BLOG_NOTICE, "invalid username/password length");
                        goto fail;
                    }
                    
                    // allocate password packet
                    bsize_t size = bsize_fromsize(1 + 1 + ai->password.username_len + 1 + ai->password.password_len);
                    if (!reserve_buffer(o, size)) {
                        goto fail;
                    }
                    
                    // write password packet
                    char *ptr = o->buffer;
                    *ptr++ = 1;
                    *ptr++ = ai->password.username_len;
                    memcpy(ptr, ai->password.username, ai->password.username_len);
                    ptr += ai->password.username_len;
                    *ptr++ = ai->password.password_len;
                    memcpy(ptr, ai->password.password, ai->password.password_len);
                    ptr += ai->password.password_len;
                    
                    // start sending
                    PacketPassInterface_Sender_Send(o->control.send_if, (uint8_t *)o->buffer, size.value);
                    
                    // set state
                    o->state = STATE_SENDING_PASSWORD;
                } break;
                
                default: ASSERT(0);
            }
        } break;
        
        case STATE_SENT_REQUEST: {
            BLog(BLOG_DEBUG, "received reply header");
            
            struct socks_reply_header imsg;
            memcpy(&imsg, o->buffer, sizeof(imsg));
            
            if (ntoh8(imsg.ver) != SOCKS_VERSION) {
                BLog(BLOG_NOTICE, "wrong version");
                goto fail;
            }
            
            if (ntoh8(imsg.rep) != SOCKS_REP_SUCCEEDED) {
                BLog(BLOG_NOTICE, "reply not successful");
                goto fail;
            }
            
            int addr_len;
            switch (ntoh8(imsg.atyp)) {
                case SOCKS_ATYP_IPV4:
                    addr_len = sizeof(struct socks_addr_ipv4);
                    break;
                case SOCKS_ATYP_IPV6:
                    addr_len = sizeof(struct socks_addr_ipv6);
                    break;
                default:
                    BLog(BLOG_NOTICE, "reply has unknown address type");
                    goto fail;
            }
            
            // receive the rest of the reply
            start_receive(o, (uint8_t *)o->buffer + sizeof(imsg), addr_len);
            
            // set state
            o->state = STATE_RECEIVED_REPLY_HEADER;
        } break;
        
        case STATE_SENT_PASSWORD: {
            BLog(BLOG_DEBUG, "received password reply");
            
            if (o->buffer[0] != 1) {
                BLog(BLOG_NOTICE, "password reply has unknown version");
                goto fail;
            }
            
            if (o->buffer[1] != 0) {
                BLog(BLOG_NOTICE, "password reply is negative");
                goto fail;
            }
            
            auth_finished(o);
        } break;
        
        case STATE_RECEIVED_REPLY_HEADER: {
            BLog(BLOG_DEBUG, "received reply rest");
            
            // free buffer
            BFree(o->buffer);
            o->buffer = NULL;
            
            // free control I/O
            free_control_io(o);
            
            // init up I/O
            init_up_io(o);
            
            // set state
            o->state = STATE_UP;
            
            // call handler
            o->handler(o->user, BSOCKSCLIENT_EVENT_UP);
            return;
        } break;
        
        default:
            ASSERT(0);
    }
    
    return;
    
fail:
    report_error(o, BSOCKSCLIENT_EVENT_ERROR);
}
示例#28
0
static void input_handler_done (SinglePacketBuffer *o, int in_len)
{
    DebugObject_Access(&o->d_obj);
    
    PacketPassInterface_Sender_Send(o->output, o->buf, in_len);
}
示例#29
0
int BPendingGroup_HasJobs (BPendingGroup *g)
{
    DebugObject_Access(&g->d_obj);
    
    return !LinkedList1_IsEmpty(&g->jobs);
}
示例#30
0
static void timer_handler (BArpProbe *o)
{
    DebugObject_Access(&o->d_obj);
    
    // send request
    send_request(o);
    
    switch (o->state) {
        case STATE_INITIAL: {
            ASSERT(o->num_missed >= 0)
            ASSERT(o->num_missed < BARPPROBE_INITIAL_NUM_ATTEMPTS)
            
            // increment missed
            o->num_missed++;
            
            // all attempts failed?
            if (o->num_missed == BARPPROBE_INITIAL_NUM_ATTEMPTS) {
                // set timer
                BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_NOEXIST_WAITRECV);
                
                // set state noexist
                o->state = STATE_NOEXIST;
                
                // report noexist
                o->handler(o->user, BARPPROBE_EVENT_NOEXIST);
                return;
            }
            
            // set timer
            BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_INITIAL_WAITRECV);
        } break;
        
        case STATE_NOEXIST: {
            // set timer
            BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_NOEXIST_WAITRECV);
        } break;
        
        case STATE_EXIST: {
            ASSERT(o->num_missed >= -1)
            ASSERT(o->num_missed < BARPPROBE_EXIST_NUM_NOREPLY)
            
            // increment missed
            o->num_missed++;
            
            // all missed?
            if (o->num_missed == BARPPROBE_EXIST_NUM_NOREPLY) {
                // set timer
                BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_PANIC_WAITRECV);
                
                // set zero missed
                o->num_missed = 0;
                
                // set state panic
                o->state = STATE_EXIST_PANIC;
                return;
            }
            
            // set timer
            BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_WAITRECV);
        } break;
        
        case STATE_EXIST_PANIC: {
            ASSERT(o->num_missed >= 0)
            ASSERT(o->num_missed < BARPPROBE_EXIST_PANIC_NUM_NOREPLY)
            
            // increment missed
            o->num_missed++;
            
            // all missed?
            if (o->num_missed == BARPPROBE_EXIST_PANIC_NUM_NOREPLY) {
                // set timer
                BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_NOEXIST_WAITRECV);
                
                // set state panic
                o->state = STATE_NOEXIST;
                
                // report noexist
                o->handler(o->user, BARPPROBE_EVENT_NOEXIST);
                return;
            }
            
            // set timer
            BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_PANIC_WAITRECV);
        } break;
    }
}