Ejemplo n.º 1
0
int32_t rtmp_core_update_inbytes(rtmp_session_t *session,
    rtmp_chunk_header_t *h,uint32_t n)
{
    int32_t      rc;

    session->in_bytes += n;
    if (session->in_bytes >= 0xf0000000) {
        session->in_bytes = 0;
        session->in_last_ack = 0;
        rtmp_log(RTMP_LOG_DEBUG,"reset byte counter");
    }

    n = session->in_bytes - session->in_last_ack;
    if (n > session->ack_window) {
        session->in_last_ack = session->in_bytes;
        rc = rtmp_create_append_chain(session,rtmp_create_ack,h);
        if (rc != RTMP_OK) {
            rtmp_log(RTMP_LOG_WARNING,"[%d]append ack "
                "message failed!",session->sid);
            return RTMP_FAILED;
        }
    }

    return RTMP_OK;
}
Ejemplo n.º 2
0
int main(int argc,char **argv)
{
    rtmp_cycle_t *rtmp_cycle;

    /*os init*/
    if (rtmp_os_init() != RTMP_OK) {
        exit(-1);
    }

    if (rtmp_strerror_init() != RTMP_OK) {
        exit(-1);
    }

    rtmp_time_update();

    if (rtmp_log_init(RTMP_LOG_DEBUG,rtmp_log_file) != RTMP_OK) {
        exit(-1);
    }

    if (rtmp_get_options(argc,argv) != RTMP_OK) {
        exit(-1);
    }

    if (rtmp_show_version) {
        rtmp_log(RTMP_LOG_INFO,"");

        if (rtmp_show_help) {
            rtmp_log(RTMP_LOG_INFO,"");
        }

        if (!rtmp_test_config) {
            return 0;
        }
    }

    /*init cycle*/
    rtmp_cycle = rtmp_init_cycle();

    if (rtmp_test_config) {

        rtmp_log(RTMP_LOG_INFO,"test file [%s] %s!",  \
            rtmp_conf_file,                           \
            (rtmp_cycle)?"ok":"failed");

        return 0;
    }

    if (rtmp_cycle == NULL) {
        rtmp_log(RTMP_LOG_ERR,"rtmp_init_cycle() failed!");
        return RTMP_FAILED;
    }

    /*run cycle*/
    rtmp_run_cycle(rtmp_cycle);

    return 0;
}
int32_t event_io_select_del(rtmp_event_io_t *io,rtmp_event_t *ev,uint32_t flag)
{
    rtmp_connection_t       *c;
    event_io_select_ctx_t   *sctx;
    rtmp_event_t            *e;
    uint32_t                 nevents;

    if (ev->index == -1) {
        rtmp_log(RTMP_LOG_WARNING,"event already!");
        return RTMP_FAILED;
    }

    sctx = io->data;
    if (sctx == NULL) {
        return RTMP_FAILED;
    }

    c = ev->data;
    ev->active = 0;

    if ((flag != EVENT_READ) && (flag != EVENT_WRITE)) {
        rtmp_log(RTMP_LOG_WARNING,"unknown flag %d",flag);
        return RTMP_FAILED;
    }

    if (flag == EVENT_READ) {
        FD_CLR(c->fd, &sctx->saved_read);
        sctx->max_read--;
    } 
    
    if (flag == EVENT_WRITE) {
        FD_CLR(c->fd, &sctx->saved_write);
        sctx->max_write--;
    }

    nevents = sctx->max_write + sctx->max_read;

    if (ev->index < (int32_t)nevents) {
        e = sctx->event_list[nevents];

        sctx->event_list[ev->index] = e;
        e->index = ev->index;
    }

    ev->index = -1;

    return RTMP_OK;
}
Ejemplo n.º 4
0
static int32_t rtmp_core_add_listening(rtmp_cycle_t *cycle,
                                       rtmp_addr_inet_t *addr)
{
    rtmp_listening_t    *ls;

    ls = array_push(&cycle->listening);
    memset(ls,0,sizeof(rtmp_listening_t));

    ls->cycle = cycle;

    ls->fd = rtmp_socket(AF_INET,SOCK_STREAM,0);
    if (ls->fd == -1) {
        rtmp_log(RTMP_LOG_WARNING,"socket() failed");
        return RTMP_FAILED;
    }

    ls->handler = rtmp_core_init_connnect;

    ls->data = addr;

    ls->sockaddr = *(struct sockaddr*)(& addr->addr);
    ls->socklen = sizeof(ls->sockaddr);

    sprintf(ls->sockaddr_text,"%s",inet_ntoa(addr[0].addr.sin_addr));

    return RTMP_OK;
}
int32_t event_io_select_init(rtmp_event_io_t *io)
{
    event_io_select_ctx_t *sctx;

    sctx = mem_calloc(sizeof(event_io_select_ctx_t) + 
        io->max_conn * 2 * sizeof(void*));

    if (sctx == NULL) {
        return RTMP_FAILED;
    }

    if (io->data) {

        rtmp_log(RTMP_LOG_WARNING,"free sctx");
        mem_free(sctx);

        io->data = 0;
    }

    io->data = sctx;

    FD_ZERO(& sctx->read_set);
    FD_ZERO(& sctx->write_set);
    FD_ZERO(& sctx->saved_read);
    FD_ZERO(& sctx->saved_write);

    return RTMP_OK;
}
Ejemplo n.º 6
0
static int32_t rtmp_core_init_cycle(rtmp_cycle_t *cycle,rtmp_module_t *module)
{

#ifndef HAVE_OS_WIN32

    rtmp_conf_t      *sconf;
    char            **word;

    sconf = rtmp_get_conf(cycle->conf,"daemon",GET_CONF_CURRENT);
    if (sconf == NULL) {
        rtmp_log(RTMP_LOG_WARNING,"no daemon!");
    }

    cycle->daemon = CONF_OFF;
    if (sconf && sconf->argv.nelts > 1) {
        word = sconf->argv.elts;


        if ((word[1][0] == 'o' || word[1][1] == 'O')
                &&(word[1][0] == 'n' || word[1][1] == 'N'))
        {
            cycle->daemon = CONF_ON;
        }
    }

    sconf = rtmp_get_conf(cycle->conf,"workers",GET_CONF_CURRENT);
    if (sconf == NULL) {
        rtmp_log(RTMP_LOG_WARNING,"no workers!");
    }

    if (sconf && sconf->argv.nelts > 1) {
        uint32_t          n;

        word = sconf->argv.elts;
        n = atoi(word[1]);
        if (n > 0) {
            cycle->workers = (uint32_t)n;
        }
    }

#endif

    return RTMP_OK;
}
Ejemplo n.º 7
0
/*max size (B)*/
void rtmp_log_set_maxsize(size_t size)
{
    if (size > 10*MB) {
        return ;
    }

    log_file.maxsize = size;
    rtmp_log(RTMP_LOG_INFO,"set size:[%d]",size);

    return ;
}
Ejemplo n.º 8
0
void rtmp_log_set_level(int level)
{
    if ((level < 0) || (level > LOG_MAX)) {
        return ;
    }

    log_file.level = level;
    rtmp_log(RTMP_LOG_INFO,"set level:[%s]",log_file.file[level]);

    return ;
}
Ejemplo n.º 9
0
void rtmp_core_free_chain(rtmp_session_t *session,
    mem_pool_t *pool,mem_buf_chain_t *chain)
{
    if (--chain->locked <= 0) {
        chain->chunk.last = chain->chunk.buf = chain->chunk_body;
        mem_free_chain_link(pool,chain);

        rtmp_log(RTMP_LOG_DEBUG,"[%d]free chain:%p .buf=%p .last=%p .end=%p",
            session->sid,chain,chain->chunk.buf,
            chain->chunk.last,chain->chunk.end);
    }
}
Ejemplo n.º 10
0
static int32_t rtmp_core_open_listennings(rtmp_cycle_t *cycle)
{
    int32_t              i;
    rtmp_listening_t    *ls;
    rtmp_connection_t   *conn;

    ls = cycle->listening.elts;

    for (i = 0; i < (int32_t)cycle->listening.nelts; i++) {
        if (ls[i].fd == -1) {
            continue;
        }

        conn = get_connection(ls,ls[i].fd);
        if (conn == NULL) {
            rtmp_log(RTMP_LOG_ERR,"get_connection() failed");
            continue;
        }

        ls[i].connection = conn;

        /*set nonblock*/
        if (set_nonblocking(ls[i].fd) != 0) {
            rtmp_log(RTMP_LOG_ERR,"set_nonblocking() failed!%d",sock_errno);
            return RTMP_FAILED;
        }

        if (bind(ls[i].fd,& ls[i].sockaddr,ls[i].socklen) == -1) {
            rtmp_log(RTMP_LOG_ERR,"bind() failed!%d",sock_errno);
            return RTMP_FAILED;
        }

        if (listen(ls[i].fd,cycle->max_conn) == -1) {
            rtmp_log(RTMP_LOG_ERR,"listen() failed!%d",sock_errno);
            return RTMP_FAILED;
        }
    }

    return RTMP_OK;
}
Ejemplo n.º 11
0
int32_t event_select_repair_fd_sets(rtmp_event_io_t *io)
{
    u_int                   i;
    int                     n;
    socklen_t               len;
    socket_t                s;
    event_io_select_ctx_t   *sctx;

    sctx = io->data;

    for (i = 0; i < sctx->saved_read.fd_count; i++) {

        s = sctx->saved_read.fd_array[i];
        len = sizeof(int);

        if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) {

            rtmp_log(RTMP_LOG_NORMAL, "invalid descriptor %d "
                "in read fd_set,err[%d]", s,sock_errno);

            FD_CLR(s, &sctx->saved_read);
        }
    }

    for (i = 0; i < sctx->saved_write.fd_count; i++) {

        s = sctx->saved_write.fd_array[i];
        len = sizeof(int);

        if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) {

            rtmp_log(RTMP_LOG_NORMAL, "invalid descriptor %d "
                "in write fd_set,err[%d]", s,sock_errno);

            FD_CLR(s, &sctx->saved_write);
        }
    }

    return RTMP_OK;
}
Ejemplo n.º 12
0
int32_t rtmp_server_handshake_done(rtmp_session_t *session)
{
    rtmp_log(RTMP_LOG_INFO,"[%d]handshake done!",session->sid);
    session->in_chain = rtmp_core_alloc_chain(session,session->c->pool,
        session->in_chunk_size);

    if (session->in_chain == NULL) {
        rtmp_session_destroy(session);
        return RTMP_FAILED;
    }

    return rtmp_core_cycle(session);
}
Ejemplo n.º 13
0
rtmp_conf_t* rtmp_conf_parse_file(char *file,mem_pool_t *pool,link_t *parent)
{
    FILE           *fp;
    long            size,r;
    char           *buf;
    rtmp_conf_t    *conf;
    rtmp_conf_buf_t block;

    conf = 0;
    fp = fopen(file,"rb");
    if (fp == NULL) {
        rtmp_log(RTMP_LOG_ERR,"file:%s open failed!",file);
        return conf;
    }

    fseek(fp,0,SEEK_END);
    size = ftell(fp);

    if (size <= 0) {
        goto done_close;
    }

    buf = mem_malloc(size+1);
    if (buf == NULL) {
        goto done_close;
    }

    rewind(fp);

    r = rtmp_read_n(fp,buf,size);
    if (r < size) {
        goto done_free;
    }
    buf[size] = '\0';

    block.line = 0;
    block.pool = pool;
    block.file = file;
    block.pos = block.start = buf;
    block.len = size;

    conf = rtmp_conf_parse_buf(&block,parent);

done_free:
    mem_free(buf);

done_close:
    fclose(fp);

    return conf;
}
Ejemplo n.º 14
0
static int32_t rtmp_connect_success_send(rtmp_session_t *session,
    rtmp_chunk_header_t *head)
{
    int32_t  rc;

    rc = rtmp_create_append_chain(session,rtmp_create_ack_size,head);
    if (rc != RTMP_OK) {
        rtmp_log(RTMP_LOG_WARNING,"[%d]append ack windows "
            "message failed!",session->sid);
        return RTMP_FAILED;
    }

    rc = rtmp_create_append_chain(session,rtmp_create_peer_bandwidth_size,head);
    if (rc != RTMP_OK) {
        rtmp_log(RTMP_LOG_WARNING,"[%d]append bandwidth "
            "message failed!",session->sid);
        return RTMP_FAILED;
    }

    rc = rtmp_create_append_chain(session,rtmp_create_set_chunk_size,head);
    if (rc != RTMP_OK) {
        rtmp_log(RTMP_LOG_WARNING,"[%d]append set chunk size "
            "message failed!",session->sid);
        return RTMP_FAILED;
    }

    if (rtmp_connect_amf_result(session,head) != RTMP_OK) {
        return RTMP_FAILED;
    }

    session->out_chunk = NULL;
    session->out_last = NULL;

    session->c->write->handler = rtmp_chain_send;
    rtmp_chain_send(session->c->write);

    return RTMP_OK;
}
Ejemplo n.º 15
0
static void *rtmp_host_create_module(rtmp_cycle_t *cycle)
{
    rtmp_hosts_ctx_t *ctx;
    mem_pool_t       *pool;

    pool = cycle->pool;
    ctx = mem_pcalloc(cycle->pool,sizeof(rtmp_hosts_ctx_t));
    if (ctx == NULL) {
        rtmp_log(RTMP_LOG_ERR,"create conf failed");
        return NULL;
    }

    if (array_init(&ctx->server_list,pool,10,sizeof(void *)) != RTMP_OK) {
        rtmp_log(RTMP_LOG_ERR,"create hosts failed");
        return NULL;
    }

    list_init(&ctx->allow_play);
    list_init(&ctx->allow_publish);
    list_init(&ctx->deny_play);
    list_init(&ctx->deny_publish);

    return (void *)ctx;
}
Ejemplo n.º 16
0
int rtmp_log_init(int level,const char* logname)
{
    if ((logname) == NULL || (level < 0) || (level >= LOG_MAX)) {
        return RTMP_FAILED;
    }

    log_file.level = level;
    do {
        strncpy(log_file.file[level],logname,511);
    } while ( --level >= 0);

#ifdef HAVE_DEBUG
    rtmp_log(RTMP_LOG_INFO,"log file:[%d]%s",level,logname);
#endif

    return RTMP_OK;
}
Ejemplo n.º 17
0
static uint32_t rtmp_os_init(void)
{
#ifdef HAVE_OS_WIN32
    WSADATA wsa;
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) {
        rtmp_log(RTMP_LOG_ERR,"WSAStartup() [%d] failed!", sock_errno);
        return RTMP_FAILED;
    }
    return RTMP_OK;
#else

    if (rtmp_init_signals() != 0) {
        return RTMP_FAILED;
    }

    return RTMP_OK;
#endif
}
Ejemplo n.º 18
0
void rtmp_core_init_connnect(rtmp_connection_t *conn)
{
    rtmp_session_t  *session;

    session = rtmp_session_create(conn);
    if (session == NULL) {
        rtmp_log(RTMP_LOG_ERR,"[%d]create session error!",conn->fd);
        free_connection(conn);
        return ;
    }

    conn->data = session;
    session->handshake->stage = RTMP_HANDSHAKE_SERVER_C0C1;

    rtmp_server_handshake(session);

    return;
}
Ejemplo n.º 19
0
int32_t rtmp_core_handle_message(rtmp_session_t *session,
    rtmp_chunk_header_t *chunk,mem_buf_chain_t *chain)
{
    rtmp_cycle_t        *cycle;
    rtmp_msg_handler_t **handler;

    cycle = session->c->listening->cycle;
    if (chunk->msgtid >= RTMP_MSG_MAX) {
        rtmp_log(RTMP_LOG_WARNING,"unknown message type id:%d",chunk->msgtid);
        return RTMP_OK;
    }

    handler = (rtmp_msg_handler_t**)cycle->msg_handler.elts;
    if (handler[chunk->msgtid]->pt) {
        mem_reset_pool(session->temp_pool);
        return handler[chunk->msgtid]->pt(session,chunk,chain);
    }

    return RTMP_OK;
}
Ejemplo n.º 20
0
mem_buf_chain_t* rtmp_core_alloc_chain(rtmp_session_t *session,
    mem_pool_t *pool,int32_t chunk_size)
{
    mem_buf_chain_t *chain;
    uint8_t         *buf;

    chain = mem_alloc_chain_link(pool);
    if (chain) {
        buf = chain->chunk_body;
        if (chain->chunk_size < (uint32_t)chunk_size) {
            buf = NULL;
        }

        if (buf == NULL) {
            buf = mem_pcalloc(pool,chunk_size + RTMP_MAX_CHUNK_HEADER);

            if (buf == NULL) {
                mem_free_chain_link(pool,chain);
                return NULL;
            }

            chain->chunk_body = buf;
            chain->chunk_size = chunk_size;
        }

        chain->chunk.buf  = buf;
        chain->chunk.last = buf;
        chain->chunk.end  = buf + chunk_size + RTMP_MAX_CHUNK_HEADER;
        chain->locked = 1;
        chain->next = NULL;

        rtmp_log(RTMP_LOG_DEBUG,"[%d]alloc chain:%p .buf=%p .last=%p .end=%p",
            session->sid,chain,chain->chunk.buf,
            chain->chunk.last,chain->chunk.end);
    }

    return chain;
}
Ejemplo n.º 21
0
int32_t rtmp_core_message_info(rtmp_session_t *session,
    rtmp_chunk_header_t *h)
{
    rtmp_chunk_stream_t *last;
    last = session->chunk_streams[h->csid];

    if (((last == NULL) && (h->fmt > 0)) || (h->csid < 2)) {
        return RTMP_FAILED;
    }

    if ((session->chunk_time == (uint32_t)-1) && h->fmt > 0) {
        return RTMP_FAILED;
    }

    switch (h->fmt) {
    case 3:
        h->dtime = last->hdr.dtime;
        h->extend = last->hdr.extend;

    case 2:
        h->msglen = last->hdr.msglen;
        h->msgtid = last->hdr.msgtid;

    case 1:
        h->msgsid = last->hdr.msgsid;

    case 0:
        break;

    default:
        rtmp_log(RTMP_LOG_DEBUG,"[%d]never reach here, csid:[%d]",
            session->sid,h->csid);

        break;
    }

    return RTMP_OK;
}
Ejemplo n.º 22
0
static void rtmp_run_workers_cycle(rtmp_cycle_t * cycle)
{
    uint32_t m;
    rtmp_module_t *module;

    for (m = 1;m < rtmp_max_modules;m++) {

        module = rtmp_modules[m];
        if (module->init_forking != NULL) {
            if (module->init_forking(cycle,module) != RTMP_OK) {
                rtmp_log(RTMP_LOG_WARNING,"forked failed[%d]",m);
                return;
            }
        }
    }

    for (;;) {
        rtmp_event_poll(80);
        rtmp_time_update();
    }

    return;
}
Ejemplo n.º 23
0
void rtmp_app_live_release(rtmp_live_link_t *link)
{
    rtmp_live_stream_t *live;

    live = link->lvst;

    if (live->publisher == link) {
        live->publisher = NULL;
    } else {
        list_remove(&link->link);
        if (link == live->players) {
            live->players = NULL;
        }
    }

    if ((live->publisher == NULL) && (live->players == NULL)) {

        rtmp_log(RTMP_LOG_DEBUG,"[%d]free live[%s]",
            link->session->sid,live->name);

        rtmp_app_live_free(link->session->app_ctx,live);
    }
    return ;
}
Ejemplo n.º 24
0
rtmp_cycle_t* rtmp_init_cycle(void)
{
    rtmp_cycle_t  *cycle;
    mem_pool_t    *pool,*temp_pool;
    size_t         slen;
    int            m;
    rtmp_module_t *module;

    mem_pagesize = 4096;
    mem_pagesize_shift = 12;
    mem_cacheline_size = 4096;

    pool = mem_create_pool(MEM_DEFAULT_POOL_SIZE);
    if (pool == NULL) {
        rtmp_log(RTMP_LOG_ERR,"alloc pool failed!");
        return NULL;
    }

    temp_pool = mem_create_pool(MEM_DEFAULT_POOL_SIZE);
    if (temp_pool == NULL) {
        rtmp_log(RTMP_LOG_ERR,"alloc temp_pool failed!");
        return NULL;
    }

    slen = strlen(rtmp_conf_file);
    cycle = mem_palloc(pool,sizeof(rtmp_cycle_t));
    if (cycle == NULL) {
        return NULL;
    }

    cycle->pool = pool;
    cycle->temp_pool = temp_pool;

    cycle->conf_file = mem_pcalloc(pool,slen + 1);
    if (cycle->conf_file == NULL) {
        return NULL;
    }
    memcpy(cycle->conf_file,rtmp_conf_file,slen);

    rtmp_max_modules = 0;
    for (m = 0;rtmp_modules[m];m++) {
        rtmp_modules[m]->index = m;
        rtmp_max_modules++;
    }
    cycle->conf = mem_pcalloc(pool,sizeof(void*));

    /*create modules*/
    for (m = 0;rtmp_modules[m];m++) {

        module = rtmp_modules[m];
        if (module->create_module != NULL) {
            module->ctx = module->create_module(cycle);
            if (module->ctx == NULL) {
                rtmp_log(RTMP_LOG_WARNING,"create module failed[%d]",m);
                return NULL;
            }
        }
    }

    if (rtmp_conf_parse(cycle) != RTMP_OK) {
        return NULL;
    }

    for (m = 0;rtmp_modules[m];m++) {

        module = rtmp_modules[m];
        if (module->init_cycle != NULL) {
            if (module->init_cycle(cycle,module) != RTMP_OK) {
                rtmp_log(RTMP_LOG_WARNING,"configure module failed[%d]",m);
                return 0;
            }
        }
    }

    /*init core process*/
    module = rtmp_modules[0];
    if (module->init_forking) {
        if (rtmp_modules[0]->init_forking(cycle,module) == RTMP_FAILED) {
            return 0;
        }
    }

    return cycle;
}
Ejemplo n.º 25
0
static int32_t rtmp_host_init_cycle(rtmp_cycle_t *cycle)
{
    rtmp_hosts_ctx_t *ctx;
    rtmp_conf_t       *conf,*it,*hostc,*appc,*apphead;
    char              *hostname,**word;
    mem_pool_t        *pool;
    rtmp_host_t       *host,**vhost;
    rtmp_app_conf_t  **app;
    rtmp_host_conf_t  *hconf;
    uint32_t           default_server;

    conf = rtmp_get_conf(cycle->conf,"rtmp",GET_CONF_CURRENT);
    if (conf == NULL) {
        return RTMP_FAILED;
    }

    ctx = rtmp_host_moudle.ctx;
    pool = cycle->pool;
    conf = rtmp_get_conf(conf,"server",GET_CONF_CHILD);
    if (conf == NULL) {
        return RTMP_FAILED;
    }

    it = conf;
    do {
        hostc = rtmp_get_conf(it,"server_name",GET_CONF_CHILD);
        default_server = 0;

        hostname = RTMP_HOSTNAME_DEF;
        if (hostc && (hostc->argv.nelts > 1)) {
            word = hostc->argv.elts;

            if ((hostc->argv.nelts > 2) && (strcmp(word[2],"default") == 0)) {
                default_server = 1;
            }

            hostname = word[1];
        }

        if (rtmp_host_conf_find(hostname,& ctx->server_list)) {
            rtmp_log(RTMP_LOG_WARNING,"server [%s] duplicate!",hostname);
            goto next_server;
        }
        
        host = mem_pcalloc(pool,sizeof(rtmp_host_t));
        if (host == NULL) {
            return RTMP_FAILED;
        }

        vhost = array_push(&ctx->server_list);
        if (!vhost) {
            rtmp_log(RTMP_LOG_ERR,"array:no more room!");
            return RTMP_FAILED;
        }
        strncpy(host->name,hostname,sizeof(host->name)-1);

        *vhost = host;

        hconf = mem_pcalloc(pool,sizeof(rtmp_host_conf_t));
        if (hconf == NULL) {
            rtmp_log(RTMP_LOG_ERR,"create host conf failed!");
            return RTMP_FAILED;
        }

        hconf->default_server = default_server;
        host->hconf = hconf;
        
        array_init(& host->apps,pool,10,sizeof(void*));
        
        if (rtmp_host_conf_init(cycle,hostc,host) != RTMP_OK) {
            rtmp_log(RTMP_LOG_ERR,"init host conf failed!");
            return RTMP_FAILED;
        }
        
        appc = rtmp_get_conf(hostc,"app",GET_CONF_NEXT);
        apphead = appc;

        do {
            if (appc == NULL) {
                break;
            }

            app = array_push(& host->apps);
            if (app == NULL) {
                rtmp_log(RTMP_LOG_ERR,"array no more room!");
                return RTMP_FAILED;
            }

            *app = mem_pcalloc(pool,sizeof(rtmp_app_conf_t));
            if (*app == NULL) {
                rtmp_log(RTMP_LOG_ERR,"alloc app failed!");
                return RTMP_FAILED;
            }

            appc = rtmp_get_conf(appc,"app",GET_CONF_NEXT);

            if (appc && appc->argv.nelts > 1) {
                rtmp_app_conf_init(cycle,appc,*app);
            }

        } while (appc != apphead);

    next_server:
        it = rtmp_get_conf(it,"server",GET_CONF_NEXT);
    } while (it && (it != conf));

    return RTMP_OK;
}
Ejemplo n.º 26
0
int32_t rtmp_amf_cmd_connect(rtmp_session_t *session,rtmp_chunk_header_t *chunk,
    amf_data_t *amf[],uint32_t num)
{
    int32_t             rc,i,h;
    double              transmitid;
    rtmp_addr_inet_t   *addr,*addrs;
    rtmp_addr_port_t   *port;
    struct sockaddr_in *addr_in;
    rtmp_host_t       **host;
    rtmp_app_t         *app;
    rtmp_session_connect_t *conn;

    if (num < 3) {
        rtmp_log(RTMP_LOG_ERR,"amf number[%d] error!",num);
        return RTMP_FAILED;
    }

    transmitid = amf_get_number(amf[1]);
    if (transmitid != 1.0) {
        rtmp_log(RTMP_LOG_ERR,"transmit id: %f",transmitid);
        return RTMP_FAILED;
    }

    rc = rtmp_amf_parse_connect(session,amf[2]);
    if (rc != RTMP_OK) {
        rtmp_log(RTMP_LOG_ERR,"[%d]rtmp_amf_parse_connect() failed!",
            session->sid);
        return RTMP_FAILED;
    }

    conn = session->conn;
    conn->trans = transmitid;

    addr = session->c->listening->data;
    if (addr->addr.sin_addr.s_addr == INADDR_ANY) {

        port = addr->port;
        addrs = port->addr_in.elts;
        addr_in = (struct sockaddr_in *)&session->c->local_sockaddr;

        for (i = port->addr_in.nelts - 1;i > 0;i--) {
            if (addrs[i].addr.sin_addr.s_addr == addr_in->sin_addr.s_addr) {
                break;
            }
        }
        addr = &addrs[i];
    }

    /*check vhost*/
    host = addr->hosts.elts;
    for (h = 0; h < (int32_t)addr->hosts.nelts;h++) {
        if (strcmp(host[h]->name,conn->vhost) == 0) {
            session->host_ctx = host[h];
            break;
        }

        if (host[h]->hconf->default_server) {
            session->host_ctx = host[h];
        }
    }

    if (session->host_ctx == 0) {
        rtmp_log(RTMP_LOG_WARNING,"[%d]check vhost:\"%s\" not found!",
            session->sid,conn->vhost);
        return RTMP_FAILED;
    }

    rtmp_log(RTMP_LOG_INFO,"[%d]check vhost=\"%s\" found!",
        session->sid,session->host_ctx->name);

    /*find app*///ÔõôѰÕÒappµÄå
    session->app_ctx = rtmp_app_conf_find(conn->app,&session->host_ctx->apps);
    if (session->app_ctx == NULL) {
        rtmp_log(RTMP_LOG_WARNING,"[%d]check app=\"%s\" not found!",
            session->sid,conn->app);

        /*send connect result*/
        (void)rtmp_connect_failed_send(session,chunk);
        return RTMP_FAILED;
    }
    app = session->app_ctx;

    rtmp_log(RTMP_LOG_INFO,"[%d]check app=\"%s\" args=\"%s\" found!",
        session->sid,conn->app,conn->args?conn->args:"(null)");

    session->chunk_pool = app->chunk_pool;
    if (app->conf->chunk_size) {
        session->out_chunk_size = app->conf->chunk_size;
    }

    return rtmp_connect_success_send(session,chunk);
}
Ejemplo n.º 27
0
int32_t rtmp_amf_parse_connect(rtmp_session_t *session,amf_data_t *amf)
{
    char                   *vhost,*ch;
    rtmp_session_connect_t *conn;

    if (session->conn != NULL) {
        rtmp_log(RTMP_LOG_ERR,"[%d]connect app \"%s\" duplicate!",
            session->sid,session->conn->app);
        return RTMP_FAILED;
    }

    conn = mem_pcalloc(session->pool,sizeof(rtmp_session_connect_t));
    if (conn == NULL) {
        rtmp_log(RTMP_LOG_ERR,"[%d]connect app \"%s\" memory failed!",
            session->sid);
        return RTMP_FAILED;
    }

    conn_app_set_string("tcUrl",tc_url,RTMP_CONN_URL_SIZE_MAX);
    conn_app_set_string("app",app,RTMP_CONN_APPNAME_SIZE_MAX);
    conn_app_set_string("pageUrl",page_url,RTMP_CONN_URL_SIZE_MAX);
    conn_app_set_string("swfUrl",swf_url,RTMP_CONN_URL_SIZE_MAX);
    conn_app_set_string("pageUrl",page_url,RTMP_CONN_URL_SIZE_MAX);
    conn_app_set_string("flashVer",flashver,RTMP_CONN_VER_SIZE_MAX);

    if (!conn->app || !conn->tc_url) {
        return RTMP_FAILED;
    }

    conn_app_set_number("audioCodecs",acodecs);
    conn_app_set_number("videoCodecs",vcodecs);
    conn_app_set_number("objectEncoding",object_encoding);

    /*get host*/
    if (memcmp("rtmp://",conn->tc_url,7) != 0) {
        return RTMP_FAILED;
    }

    vhost = mem_dup_str(conn->tc_url+7,session->pool);
    strtok(vhost,":/");

    ch = vhost;
    for (ch = vhost;*ch;ch++) {
        if (*ch == ':' || *ch == '/') {
            *ch = 0;
            break;
        }
    }

    conn->vhost = vhost;
    ch = strchr(conn->app,'?');
    if (ch) {
        *ch++ = 0;
        conn->args = mem_pcalloc(session->pool,RTMP_CONN_ARGS_SIZE_MAX);
        if (conn->args) {
            strncpy(conn->args,ch,RTMP_CONN_ARGS_SIZE_MAX - 1);
        }
    }

    session->conn = conn;
    return RTMP_OK;
}
Ejemplo n.º 28
0
int32_t event_io_select_add(rtmp_event_io_t *io,rtmp_event_t *ev,uint32_t flag)
{
    rtmp_connection_t       *c;
    event_io_select_ctx_t   *sctx;
    uint32_t                 nevents;

    if (ev->index != -1) {
        rtmp_log(RTMP_LOG_WARNING,"event already!");
        return RTMP_FAILED;
    }

    c = ev->data;

    sctx = io->data;
    if (sctx == NULL) {
        return RTMP_FAILED;
    }

    if ((flag != EVENT_READ) && (flag != EVENT_WRITE)) {
        rtmp_log(RTMP_LOG_WARNING,"unknown flag %d",flag);
        return RTMP_FAILED;
    }

    if (flag == EVENT_READ) {
        
        if (ev->write) {
            rtmp_log(RTMP_LOG_ERR,"read event");
            return RTMP_FAILED;
        }

        if (sctx->max_read >= FD_SETSIZE) {
            rtmp_log(RTMP_LOG_ERR,"too many read events");
            return RTMP_FAILED;
        }

        FD_SET(c->fd, &sctx->saved_read);
        sctx->max_read++;
    }

    if (flag == EVENT_WRITE) {
        
        if (!ev->write) {
            rtmp_log(RTMP_LOG_ERR,"write event");
            return RTMP_FAILED;
        }

        if (sctx->max_write >= FD_SETSIZE) {
            rtmp_log(RTMP_LOG_ERR,"too many write events");
            return RTMP_FAILED;
        }

        FD_SET(c->fd, &sctx->saved_write);
        sctx->max_write++;
    }
    
    nevents = sctx->max_read + sctx->max_write - 1;

    ev->active = 1;
    sctx->event_list[nevents] = ev;
    ev->index = nevents;

    return RTMP_OK;
}
Ejemplo n.º 29
0
static int
rtmp_get_options(int argc, char *const *argv)
{
    char     *p;
    int      i;

    for (i = 1; i < argc; i++) {

        p = argv[i];

        if (*p++ != '-') {
            return RTMP_ERROR;
        }

        while (*p) {

            switch (*p++) {

            case '?':
            case 'h':
                rtmp_show_version = 1;
                rtmp_show_help = 1;
                break;

            case 'l':
                if (*p) {
                    rtmp_log_file = p;
                    continue;
                }

                if (argv[++i]) {
                    rtmp_log_file = argv[i];
                    continue;
                }

                rtmp_log(RTMP_LOG_ERR, "option \"-l\" requires file name");
                return RTMP_ERROR;

            case 'c':
                if (*p) {
                    rtmp_conf_file = p;
                    continue;
                }

                if (argv[++i]) {
                    rtmp_conf_file = argv[i];
                    continue;
                }

                rtmp_log(RTMP_LOG_ERR, "option \"-c\" requires file name");
                return RTMP_ERROR;

            case 'v':
            case 'V':
                rtmp_show_version = 1;
                break;

            case 't':
                rtmp_test_config = 1;
                break;

            case 's':
                if (*p == 0) {
                    p = argv[i];
                }

                if (strcmp(p,"stop") == 0) {
                    rtmp_sigal_stop = 1;
                }

                if (strcmp(p,"reload") == 0) {
                    rtmp_sigal_reload = 1;
                }

                rtmp_log(RTMP_LOG_ERR, "option \"-s\" requires parameter");
                return RTMP_ERROR;

            default:
                rtmp_log(RTMP_LOG_ERR, "invalid option: \"%c\"", *(p - 1));
                return RTMP_ERROR;

            }
        }
    }

    return RTMP_OK;
}
Ejemplo n.º 30
0
static uint32_t rtmp_connect_amf_result(rtmp_session_t *session,
    rtmp_chunk_header_t *head)
{
    amf_data_t          *amf[4],*ecma;
    mem_buf_t           *buf;
    mem_buf_chain_t     *chain;
    rtmp_chunk_header_t  hdr;

    amf[0] = amf_new_string("_result",0);
    amf[1] = amf_new_number(1.0);
    amf[2] = amf_new_object();

    /*properties*/
    if (amf[2]) {
        amf_put_prop(amf[2],"fmsVer",
            amf_new_string("FMS/"rtmp_sig_fms_ver,0));

        amf_put_prop(amf[2],"capabilities",amf_new_number(255));
        amf_put_prop(amf[2],"mode",amf_new_number(1));
    }

    /*informations*/
    amf[3] = amf_new_object();
    if (amf[3]) {
        amf_put_prop(amf[3],"level",amf_new_string("status",0));
        amf_put_prop(amf[3],"code",
            amf_new_string("NetConnection.Connect.Success",0));

        amf_put_prop(amf[3],"description",
            amf_new_string("Connection succeeded.",0));

        amf_put_prop(amf[3],"objectEncoding",
            amf_new_number(session->conn->object_encoding));

        ecma = amf_new_ecma_array();
        if (ecma) {
            amf_put_prop(ecma,"version",
                amf_new_string(rtmp_sig_fms_ver,0));

            amf_put_prop(amf[3],"data",ecma);
        }
    }

    buf = rtmp_prepare_amf_buffer(session->temp_pool,amf,4);
    if (buf == NULL) {
        return RTMP_FAILED;
    }

    chain = rtmp_copy_buf_to_chain(session,buf);
    if (chain == NULL) {
        rtmp_log(RTMP_LOG_WARNING,"prepare connect app message failed!");
        return RTMP_FAILED;
    }

    hdr = *head;
    hdr.msglen = buf->last - buf->buf;
    hdr.fmt = 0;

    if (rtmp_append_message_chain(session,chain,&hdr) == -1) {
        rtmp_log(RTMP_LOG_WARNING,"append connect app message failed!");
        return RTMP_FAILED;
    }

    return  0;
}