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; }
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; }
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; }
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; }
/*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 ; }
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 ; }
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); } }
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; }
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; }
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); }
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; }
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; }
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; }
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; }
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 }
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; }
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; }
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; }
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; }
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; }
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 ; }
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; }
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; }
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); }
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; }
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; }
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; }
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; }