bool us_http_server_handler_dispatch(us_http_server_handler_t *self) {
    bool r = false;
    us_buffer_t *incoming = &self->m_base.m_incoming_queue;
    us_buffer_t *outgoing = &self->m_base.m_outgoing_queue;
    us_log_tracepoint();
    if (self->m_director->dispatch(
            self->m_director, self->m_request_header, incoming, self->m_response_header, self->m_response_content) >= 0) {
        r = us_http_response_header_flatten(self->m_response_header, outgoing);
        if (r) {
            /* Send content if it was not a HEAD request */
            if (strcmp(self->m_request_header->m_method, "HEAD") != 0) {
                if (us_buffer_writable_count(outgoing) > us_buffer_readable_count(self->m_response_content)) {
                    us_buffer_write_buffer(outgoing, self->m_response_content);
                    us_http_server_handler_set_state_sending_response(self);
                    /* response header and response content is now in the outgoing buffer */
                    r = true;
                    us_log_debug("response header and content ready");
                } else {
                    r = false;
                    us_log_error("unable to buffer http response content");
                }
            } else {
                us_http_server_handler_set_state_sending_response(self);
                r = true;
            }
        } else {
            us_log_error("unable to flatten response header");
        }
    }
    if (!r) {
        self->m_base.close(&self->m_base);
    }
    return r;
}
示例#2
0
bool us_rawnet_join_multicast(us_rawnet_context_t *self, const uint8_t multicast_mac[6]) {
    bool r = false;
    struct packet_mreq mreq;
    struct sockaddr_ll saddr;
    if (multicast_mac) {
        memset(&saddr, 0, sizeof(saddr));
        saddr.sll_family = AF_PACKET;
        saddr.sll_ifindex = self->m_interface_id;
        saddr.sll_pkttype = PACKET_MULTICAST;
        saddr.sll_protocol = htons(self->m_ethertype);
        if (bind(self->m_fd, (struct sockaddr *)&saddr, sizeof(saddr)) >= 0) {
            memset(&mreq, 0, sizeof(mreq));
            mreq.mr_ifindex = self->m_interface_id;
            mreq.mr_type = PACKET_MR_MULTICAST;
            mreq.mr_alen = 6;
            mreq.mr_address[0] = multicast_mac[0];
            mreq.mr_address[1] = multicast_mac[1];
            mreq.mr_address[2] = multicast_mac[2];
            mreq.mr_address[3] = multicast_mac[3];
            mreq.mr_address[4] = multicast_mac[4];
            mreq.mr_address[5] = multicast_mac[5];
            if (setsockopt(self->m_fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) >= 0) {
                r = true;
            } else {
                us_log_error("us_rawnet_join_multicast setsockopt[SOL_SOCKET,PACKET_ADD_MEMBERSHIP] error %s", strerror(errno));
            }
        } else {
            us_log_error("us_rawnet_join_multicast bind error: %s", strerror(errno));
        }
    }
    return r;
}
示例#3
0
void us_allocator_heap_internal_free( us_allocator_heap_t *self, void *ptr )
{
    us_allocator_heap_pack( self, self->m_first );
    /* only free non-null pointers */
    us_allocator_heap_validate( self );
    if ( ptr != 0 )
    {
        /*
           subtract the MemBlock header size from the pointer given to us
           to get the MemBlock header address
        */
        us_allocator_heap_block_t *block
            = (us_allocator_heap_block_t *)( ( (unsigned long long)ptr ) - us_allocator_rounded_block_size );
        if ( block->m_magic != US_HEAP_MAGIC )
        {
            us_log_error( "bad magic" );
            abort();
        }
        us_allocator_heap_validate_block( block );
        /* mark it as free by changing the size to negative size */
        if ( block->m_size > 0 )
        {
            ssize_t sz = block->m_size;
            self->m_current_allocation_count -= sz;
            block->m_size = -sz;
        }
        else
        {
            us_log_error( "attempt to double free a memory heap block" );
        }
        /* call pack() to pack it and any free blocks before and after it */
        us_allocator_heap_pack( self, block );
    }
}
示例#4
0
bool us_rawnet_join_multicast( us_rawnet_context_t *self, const uint8_t multicast_mac[6] )
{
    bool r = false;
    struct bpf_program fcode;
    pcap_t *p = (pcap_t *)self->m_pcap;
    char filter[1024];
    /* TODO: add multicast address to pcap filter here if multicast_mac is not null*/
    (void)multicast_mac;
    sprintf( filter, "ether proto 0x%04x", self->m_ethertype );

    if ( pcap_compile( p, &fcode, filter, 1, 0xffffffff ) < 0 )
    {
        pcap_close( p );
        us_log_error( "Unable to pcap_compile: '%s'", filter );
    }
    else
    {
        if ( pcap_setfilter( p, &fcode ) < 0 )
        {
            pcap_close( p );
            us_log_error( "Unable to pcap_setfilter" );
        }
        else
        {
            r = true;
        }
        pcap_freecode( &fcode );
    }
    return r;
}
bool us_http_server_handler_init(us_reactor_handler_t *self_,
                                 us_allocator_t *allocator,
                                 int fd,
                                 void *extra,
                                 int32_t max_response_buffer_size,
                                 us_webapp_director_t *director) {
    bool r = false;
    us_http_server_handler_t *self = (us_http_server_handler_t *)self_;
    us_log_tracepoint();
    r = us_reactor_handler_tcp_init(&self->m_base.m_base, allocator, fd, extra, max_response_buffer_size);
    self->m_base.m_base.destroy = us_http_server_handler_destroy;
    if (r) {
        int32_t local_allocator_size = US_HTTP_SERVER_HANDLER_LOCAL_BUFFER_SIZE + max_response_buffer_size;
        self->m_local_allocator_buffer = us_new_array(allocator, char, local_allocator_size);
        self->m_request_header = 0;
        self->m_response_header = 0;
        if (self->m_local_allocator_buffer) {
            us_simple_allocator_init(&self->m_local_allocator, self->m_local_allocator_buffer, local_allocator_size);
            self->m_request_header = us_http_request_header_create(&self->m_local_allocator.m_base);
            self->m_response_header = us_http_response_header_create(&self->m_local_allocator.m_base);
            self->m_response_content = us_buffer_create(&self->m_local_allocator.m_base, max_response_buffer_size);
            self->m_director = director;
            if (self->m_request_header && self->m_response_header && self->m_response_content) {
                us_http_server_handler_set_state_waiting_for_connection(self);
                r = true;
            }
        }
    }
    if (!r) {
        us_log_error("Unable to init http server handler");
        self->m_base.m_base.destroy(&self->m_base.m_base);
    }
    return r;
}
示例#6
0
void us_daemon_end(void)
{
    close( us_daemon_pid_fd );
    if( strlen(us_daemon_pid_file_name)>0 )
    {
        if( unlink( us_daemon_pid_file_name )<0 )
        {
            us_log_error("remove pid file failed: %s", strerror(errno));
        }
    }
}
int us_test_trie_main(int argc, const char **argv) {
    int r = 1;
    if (us_testutil_start(8192, 8192, argc, argv)) {
#if US_ENABLE_LOGGING
        us_logger_printer_start(us_testutil_printer_stdout, us_testutil_printer_stderr);
#endif
        us_log_set_level(US_LOG_LEVEL_DEBUG);
        us_log_info("Hello world from %s compiled on %s", __FILE__, __DATE__);
        if (us_test_trie_1() && us_test_trie_2())
            r = 0;
        if (r != 0)
            us_log_error("Failed");
        us_log_info("Finishing %s", argv[0]);
        us_logger_finish();
        us_testutil_finish();
    }
    return r;
}
int main( int argc, const char **argv )
{
    if ( jdksavdecc_logger_init( argv ) )
    {
        while ( true )
        {
            time_t cur_time = time( 0 );
            if ( us_platform_sigint_seen || us_platform_sigterm_seen )
            {
                break;
            }
#if defined( WIN32 )
            Sleep( 100 );
#else
            fd_set readable;
            int largest_fd = -1;
            int s;
            struct timeval tv;
            FD_ZERO( &readable );
            largest_fd = us_rawnet_multi_set_fdset( &multi_rawnet, &readable );
            tv.tv_sec = 0;
            tv.tv_usec = 200000; // 200 ms

            do
            {
                s = select( largest_fd + 1, &readable, 0, 0, &tv );
            } while ( s < 0 && ( errno == EINTR || errno == EAGAIN ) );

            if ( s < 0 )
            {
                us_log_error( "Unable to select" );
                break;
            }
#endif
            // poll even if select thinks there are no readable sockets
            us_rawnet_multi_rawnet_poll_incoming( &multi_rawnet, cur_time, 128, 0, incoming_packet_handler );
        }

        jdksavdecc_logger_destroy();
    }
    return 0;
}
示例#9
0
void us_allocator_heap_validate_block( us_allocator_heap_block_t *block )
{
    if ( (uint64_t)block < 0x1000 && block != 0 )
    {
        us_log_error( "block is bad" );
        abort();
    }
    if ( block )
    {
        if ( block->m_magic != US_HEAP_MAGIC )
        {
            us_log_error( "block->m_magic is bad" );
            abort();
        }
        if ( (uint64_t)block->m_next < 0x1000 && (uint64_t)block->m_next != 0 )
        {
            us_log_error( "block->m_next is bad" );
            abort();
        }
        if ( (uint64_t)block->m_prev < 0x1000 && (uint64_t)block->m_prev != 0 )
        {
            us_log_error( "block->m_prev is bad" );
            abort();
        }
        if ( ( (uint64_t)block->m_prev != 0 ) && ( block->m_prev->m_next != block ) )
        {
            us_log_error( "block->m_prev->m_next is bad" );
            abort();
        }
        if ( ( (uint64_t)block->m_next != 0 ) && ( block->m_next->m_prev != block ) )
        {
            us_log_error( "block->m_next->m_prev is bad" );
            abort();
        }
    }
}
示例#10
0
int
us_rawnet_socket(us_rawnet_context_t *self, uint16_t ethertype, const char *interface_name, const uint8_t join_multicast[6]) {
    int r = -1;
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t *p;

    self->m_ethertype = ethertype;
    if( join_multicast ) {
        memcpy( self->m_default_dest_mac, join_multicast, 6 );
    }

    p = pcap_open_live(interface_name, 65536, 1, 1, errbuf);
    self->m_pcap = (void *)p;

    if (!p) {
        us_log_error("pcap open error on interface '%s': %s", interface_name, errbuf);
    } else {
        int dl = pcap_datalink(p);

        if (dl != DLT_EN10MB && dl != DLT_IEEE802_11) {
            us_log_error("Interface %s is not an Ethernet or wireless interface", interface_name);
        } else {
            pcap_if_t *d=0;
            self->m_interface_id = -1;
            if( us_rawnet_alldevs==0 ) {
                if (pcap_findalldevs(&us_rawnet_alldevs, errbuf) != 0 || us_rawnet_alldevs==0) {
                    us_log_error("pcap_findalldevs failed");
                    pcap_close(p);
                    return -1;
                }
                atexit(us_rawnet_cleanup);
            }
            {
                for (d = us_rawnet_alldevs; d != NULL; d = d->next) {
                    self->m_interface_id++;

                    /* find the interface by name */
                    if (strcmp(interface_name, d->name) == 0) {
/* now find the MAC address associated with it */
#if defined(_WIN32)
                        PIP_ADAPTER_INFO info = NULL, ninfo;
                        ULONG ulOutBufLen = 0;
                        DWORD dwRetVal = 0;
                        if (GetAdaptersInfo(info, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
                            info = (PIP_ADAPTER_INFO)malloc(ulOutBufLen);
                            if (info != NULL) {
                                if ((dwRetVal = GetAdaptersInfo(info, &ulOutBufLen)) == NO_ERROR) {
                                    ninfo = info;
                                    while (ninfo != NULL) {
                                        if (strstr(d->name, ninfo->AdapterName) > 0) {
                                            if (ninfo->AddressLength == 6)
                                                memcpy(self->m_my_mac, ninfo->Address, 6);
                                            break;
                                        }
                                        ninfo = ninfo->Next;
                                    }
                                } else
                                    us_log_error("Error in GetAdaptersInfo");
                                free(info);
                            } else {
                                us_log_error("Error in malloc for GetAdaptersInfo");
                            }
                        }
#else
                        pcap_addr_t *alladdrs;
                        pcap_addr_t *a;
                        alladdrs = d->addresses;
                        for (a = alladdrs; a != NULL; a = a->next) {
#if defined(__APPLE__)
                            /* Apple AF_LINK format depends on osx version */

                            if (a->addr->sa_family == AF_LINK && a->addr->sa_data != NULL) {
                                struct sockaddr_dl *link = (struct sockaddr_dl *)a->addr->sa_data;

                                uint8_t mac[link->sdl_alen];
                                memcpy(mac, LLADDR(link), link->sdl_alen);

                                if (link->sdl_alen == 6) {
                                    /* older mac os x */
                                    memcpy(self->m_my_mac, &mac[0], 6);
                                } else if (link->sdl_alen > 6) {
                                    /* newer mac os x */
                                    memcpy(self->m_my_mac, &mac[1], 6);
                                }
                                break;
                            }
#elif defined(__linux__)
                            if (a->addr->sa_family == AF_PACKET) {
                                struct sockaddr_ll *link = (struct sockaddr_ll *)a->addr;
                                memcpy(self->m_my_mac, link->sll_addr, 6);
                                break;
                            }
#endif
                        }
#endif
                        break;
                    }
                }

                if (self->m_interface_id == -1) {
                    us_log_error("unable to get MAC address for interface '%s'", interface_name);
                } else {
                    /* enable ether protocol filter */
                    us_rawnet_join_multicast(self, join_multicast);
                    self->m_fd = pcap_fileno(p);
                    if (self->m_fd == -1) {
                        us_log_error("Unable to get pcap fd");
                    } else {
                        r = self->m_fd;
                    }
                }
            }
        }
    }

    if (r == -1) {
        if (p) {
            pcap_close(p);
            self->m_pcap = 0;
        }
    } else {
        us_net_set_socket_nonblocking(r);
    }
    return r;
}
static us_osc_msg_t * us_tool_gen_osc(
    us_allocator_t *allocator,
    const char *osc_address,
    const char *osc_typetags,
    const char **osc_values
)
{
    us_osc_msg_t *r = 0;
    us_osc_msg_t *self;
    const char *t=osc_typetags;
    us_osc_msg_element_t *e;
    if ( *t==',' )
        ++t;
    self = us_osc_msg_create( allocator, osc_address );
    if ( self )
    {
        r = self;
        for ( ; *t!=0; ++t )
        {
            e = 0;
            switch ( *t )
            {
            case 'a':
            {
                uint32_t high, low;
                if( !*osc_values )
                {
                    us_log_error( "Missing osc_value a" );
                    r=0;
                    break;
                }
                uint64_t val = strtoull( *osc_values, 0, 10 );
                high = (uint32_t)((val>>32)&0xffffffff);
                low = (uint32_t)(val&0xffffffff);
                e = us_osc_msg_element_a_create( allocator, high, low );
                osc_values++;
            }
            break;
            case 'b':
            {
                uint8_t valbuf[256];
                const char *s;
                size_t sz;
                size_t octet_count;
                if( !*osc_values )
                {
                    us_log_error( "Missing osc_value b" );
                    r=0;
                    break;
                }
                s = *osc_values;
                sz = strlen(s);
                octet_count=sz/2;
                if( (sz&1)==0 )
                {
                    bool parsed=true;
                    size_t i;
                    size_t pos=0;
                    for( i=0; i<octet_count; ++i )
                    {
                        parsed&=us_parse_hexoctet(
                                    &valbuf[i],
                                    s,
                                    sz,
                                    &pos
                                );
                        if( !parsed )
                        {
                            us_log_error( "unable to parse hex octets in '%s'", s );
                            r=0;
                            break;
                        }
                    }
                    if( parsed )
                    {
                        e = us_osc_msg_element_b_create(
                                allocator,
                                valbuf,
                                octet_count
                            );
                        osc_values++;
                    }
                }
                else
                {
                    us_log_error( "'b' type needs even number of octets" );
                    r=0;
                    break;
                }
            }
            break;
#if US_ENABLE_DOUBLE
            case 'd':
            {
                double v;
                if( !*osc_values )
                {
                    us_log_error( "Missing osc_value d" );
                    r=0;
                    break;
                }
                v = strtod( *osc_values, 0 );
                e = us_osc_msg_element_d_create( allocator, v );
                osc_values++;
            }
            break;
#endif
            case 'F':
            {
                e = us_osc_msg_element_F_create( allocator );
            }
            break;
#if US_ENABLE_FLOAT
            case 'f':
            {
                float v;
                if( !*osc_values )
                {
                    us_log_error( "Missing osc_value f" );
                    r=0;
                    break;
                }
                v = atof( *osc_values );
                e = us_osc_msg_element_f_create( allocator, v );
                osc_values++;
            }
            break;
#endif
            case 'h':
            {
                uint32_t high, low;
                uint64_t val;
                if( !*osc_values )
                {
                    us_log_error( "Missing osc_value h" );
                    r=0;
                    break;
                }
                val = strtoull( *osc_values, 0, 10 );
                high = (uint32_t)((val>>32)&0xffffffff);
                low = (uint32_t)(val&0xffffffff);
                e = us_osc_msg_element_h_create( allocator, high, low );
                osc_values++;
            }
            break;
            case 'I':
            {
                e = us_osc_msg_element_I_create( allocator );
            }
            break;
            case 'i':
            {
                int32_t v;
                if( !*osc_values )
                {
                    us_log_error( "Missing osc_value i" );
                    r=0;
                    break;
                }
                v = strtol( *osc_values, 0, 10 );
                e = us_osc_msg_element_i_create( allocator, v );
                osc_values++;
            }
            break;
            case 'N':
            {
                e = us_osc_msg_element_N_create( allocator );
            }
            break;
            case 's':
            {
                const char *s;
                if( !*osc_values )
                {
                    us_log_error( "Missing osc_value s" );
                    r=0;
                    break;
                }
                s = *osc_values;
                e = us_osc_msg_element_s_create( allocator, s );
                osc_values++;
            }
            break;
            case 'T':
            {
                e = us_osc_msg_element_T_create( allocator );
            }
            break;
            case 't':
            {
                uint32_t high, low;
                uint64_t val;
                if( !*osc_values )
                {
                    us_log_error( "Missing osc_value t" );
                    r=0;
                    break;
                }
                val = strtoull( *osc_values, 0, 10 );
                high = (uint32_t)((val>>32)&0xffffffff);
                low = (uint32_t)(val&0xffffffff);
                e = us_osc_msg_element_t_create( allocator, high, low );
                osc_values++;
            }
            break;
            default:
            {
                e = 0;
            }
            break;
            }
            if ( e )
            {
                self->append( self, e );
            }
            else
            {
                r = 0;
                break;
            }
        }
    }
    return r;
}
示例#12
0
void us_daemon_daemonize(
    bool real_daemon,
    const char * identity,
    const char * home_dir,
    const char * pid_file,
    const char * new_uid
)
{
    /* remember the pid file name */
    us_strncpy( us_daemon_pid_file_name, pid_file, 1024 );
    if( strlen(home_dir)>0 )
    {
        mkdir(home_dir,0750);
        chdir(home_dir);
    }
    if( real_daemon )
    {
        switch(fork())
        {
        case -1:
            perror( "fork() failed" );
            exit(1);
        case 0:
            break;
        default:
            _exit(0);
            break;
        };
    }
    if( strlen(new_uid)>0 )
    {
        us_daemon_drop_root(new_uid);
    }
    if( real_daemon )
    {
        int fd;
        for( fd=0; fd<getdtablesize(); ++fd )
        {
            close(fd);
        }
        fd = open("/dev/null", O_RDWR );
        dup2(fd, STDIN_FILENO);
        dup2(fd, STDOUT_FILENO);
        dup2(fd, STDERR_FILENO);
    }
    umask(027);
    if( strlen(us_daemon_pid_file_name)>0 )
    {
        us_daemon_pid_fd = open( us_daemon_pid_file_name, O_CREAT | O_TRUNC | O_WRONLY , 0640 );
        if( us_daemon_pid_fd>=0 )
        {
            char tmpbuf[64];
            if( lockf(us_daemon_pid_fd,F_TLOCK,0)<0)
            {
                us_log_error( "Unable to lock pid file: %s", us_daemon_pid_file_name );
                abort();
            }
            sprintf( tmpbuf, "%ld\n", (long)getpid() );
            size_t len = strlen(tmpbuf);
            if( write( us_daemon_pid_fd, tmpbuf, len)!=len )
            {
                us_log_error( "Error writing pid file: %s", us_daemon_pid_file_name );
                abort();
            }
            atexit( us_daemon_end );
        }
        else
        {
            us_log_error("Error creating pid file: %s", us_daemon_pid_file_name );
            abort();
        }
    }
    us_daemon_prepare_child_start();
}