int SrsConnection::cycle() { int ret = ERROR_SUCCESS; _srs_context->generate_id(); ip = srs_get_peer_ip(st_netfd_fileno(stfd)); ret = do_cycle(); // if socket io error, set to closed. if (srs_is_client_gracefully_close(ret)) { ret = ERROR_SOCKET_CLOSED; } // success. if (ret == ERROR_SUCCESS) { srs_trace("client finished."); } // client close peer. if (ret == ERROR_SOCKET_CLOSED) { srs_warn("client disconnect peer. ret=%d", ret); } // set loop to stop to quit. pthread->stop_loop(); return ERROR_SUCCESS; }
int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd) { int ret = ERROR_SUCCESS; int max_connections = _srs_config->get_max_connections(); if ((int)conns.size() >= max_connections) { int fd = st_netfd_fileno(client_stfd); srs_error("exceed the max connections, drop client: " "clients=%d, max=%d, fd=%d", (int)conns.size(), max_connections, fd); srs_close_stfd(client_stfd); return ret; } SrsConnection* conn = NULL; if (type == SrsListenerRtmpStream) { conn = new SrsRtmpConn(this, client_stfd); } else if (type == SrsListenerHttpApi) { #ifdef SRS_AUTO_HTTP_API conn = new SrsHttpApi(this, client_stfd, http_api_handler); #else srs_warn("close http client for server not support http-api"); srs_close_stfd(client_stfd); return ret; #endif } else if (type == SrsListenerHttpStream) { #ifdef SRS_AUTO_HTTP_SERVER conn = new SrsHttpConn(this, client_stfd, http_stream_handler); #else srs_warn("close http client for server not support http-server"); srs_close_stfd(client_stfd); return ret; #endif } else { // TODO: FIXME: handler others } srs_assert(conn); // directly enqueue, the cycle thread will remove the client. conns.push_back(conn); srs_verbose("add conn to vector."); // cycle will start process thread and when finished remove the client. // @remark never use the conn, for it maybe destroyed. if ((ret = conn->start()) != ERROR_SUCCESS) { return ret; } srs_verbose("conn started success."); srs_verbose("accept client finished. conns=%d, ret=%d", (int)conns.size(), ret); return ret; }
static void pt_sig_catcher(int signo) { int err, fd; err = errno; fd = st_netfd_fileno(_sig_pipe[1]); /* write() is async-safe */ write(fd, &signo, sizeof(int)); errno = err; }
void srs_close_stfd(st_netfd_t& stfd) { if (stfd) { int fd = st_netfd_fileno(stfd); st_netfd_close(stfd); stfd = NULL; // st does not close it sometimes, // close it manually. close(fd); } }
static void child_sighandler(int signo) { int err, fd; err = errno; fd = st_netfd_fileno(sig_pipe[1]); /* write() is async-safe */ if (write(fd, &signo, sizeof(int)) != sizeof(int)) err_sys_quit(errfd, "ERROR: process %d (pid %d): child's signal" " handler: write", my_index, my_pid); errno = err; }
void srs_close_stfd(st_netfd_t& stfd) { if (stfd) { int fd = st_netfd_fileno(stfd); st_netfd_close(stfd); stfd = NULL; // st does not close it sometimes, // close it manually. #ifndef WIN32 close(fd); #else closesocket(fd); #endif } }
int SrsListener::cycle() { int ret = ERROR_SUCCESS; st_netfd_t client_stfd = st_accept(stfd, NULL, NULL, ST_UTIME_NO_TIMEOUT); if(client_stfd == NULL){ // ignore error. srs_warn("ignore accept thread stoppped for accept client error"); return ret; } srs_verbose("get a client. fd=%d", st_netfd_fileno(client_stfd)); if ((ret = server->accept_client(type, client_stfd)) != ERROR_SUCCESS) { srs_warn("accept client error. ret=%d", ret); return ret; } return ret; }
static void *handle_request(void *arg) { struct pollfd pds[2]; st_netfd_t cli_nfd, rmt_nfd; int sock, n; char buf[IOBUFSIZE]; cli_nfd = (st_netfd_t) arg; pds[0].fd = st_netfd_fileno(cli_nfd); pds[0].events = POLLIN; /* Connect to remote host */ if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { print_sys_error("socket"); goto done; } if ((rmt_nfd = st_netfd_open_socket(sock)) == NULL) { print_sys_error("st_netfd_open_socket"); close(sock); goto done; } if (st_connect(rmt_nfd, (struct sockaddr *)&rmt_addr, sizeof(rmt_addr), -1) < 0) { print_sys_error("st_connect"); st_netfd_close(rmt_nfd); goto done; } pds[1].fd = sock; pds[1].events = POLLIN; /* Now just pump the data through */ for ( ; ; ) { pds[0].revents = 0; pds[1].revents = 0; if (st_poll(pds, 2, -1) <= 0) { print_sys_error("st_poll"); break; } if (pds[0].revents & POLLIN) { if ((n = (int) st_read(cli_nfd, buf, IOBUFSIZE, -1)) <= 0) break; if (st_write(rmt_nfd, buf, n, -1) != n) break; } if (pds[1].revents & POLLIN) { if ((n = (int) st_read(rmt_nfd, buf, IOBUFSIZE, -1)) <= 0) break; if (st_write(cli_nfd, buf, n, -1) != n) break; } } st_netfd_close(rmt_nfd); done: st_netfd_close(cli_nfd); return NULL; }
int pushto(st_netfd_t rmt_nfd, struct thr_data *td) { FILE *in; char buffer[BUFSIZ]; struct stat st; int filesize; int i, len; struct q_info *q = td->q; char *basename; if ((basename = strrchr(td->filename, '/')) == NULL) { basename = td->filename; } else { basename++; } if (stat(td->filename, &st)) { LOG(LOG_WARNING, "%s: %m", td->filename); return 0; } filesize = (int) st.st_size; if (filesize == 0) { LOG(LOG_WARNING, "zero size: %s", td->filename); return 1; } // expect: +OK UpWatch Acceptor vx.xx. Please login memset(buffer, 0, sizeof(buffer)); len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout reading login request string"); } else { LOG(LOG_WARNING, "read: %m"); } return 0; } if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer); if (buffer[0] != '+') { LOG(LOG_WARNING, buffer); return 0; } sprintf(buffer, "USER %s\n", q->user); uw_setproctitle("%s:%d %s", q->host, q->port, buffer); if (debug > 3) fprintf(stderr, "%s[%u] > %s", q->host, st_netfd_fileno(rmt_nfd), buffer); len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout writing %s", buffer); } else { LOG(LOG_WARNING, "write: %m"); } return 0; } // expect here: +OK Please enter password memset(buffer, 0, sizeof(buffer)); len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout reading OK enter password"); } else { LOG(LOG_WARNING, "read: %m"); } return 0; } if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer); if (buffer[0] != '+') { LOG(LOG_WARNING, buffer); return 0; } sprintf(buffer, "PASS %s\n", q->pwd); uw_setproctitle("%s:%d PASS xxxxxxxx", q->host, q->port); if (debug > 3) fprintf(stderr, "%s[%u] > %s", q->host, st_netfd_fileno(rmt_nfd), buffer); len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout writing %s", buffer); } else { LOG(LOG_WARNING, "write: %m"); } return 0; } // expect here: +OK logged in, enter command memset(buffer, 0, sizeof(buffer)); len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout reading enter command"); } else { LOG(LOG_WARNING, "read: %m"); } return 0; } if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer); if (buffer[0] != '+') { LOG(LOG_WARNING, buffer); return 0; } sprintf(buffer, "DATA %d %s\n", filesize, basename); uw_setproctitle("%s:%d %s", q->host, q->port, buffer); if (debug > 3) fprintf(stderr, "%s[%u] > %s", q->host, st_netfd_fileno(rmt_nfd), buffer); len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout writing %s", buffer); } else { LOG(LOG_WARNING, "write: %m"); } return 0; } // expect here: +OK start sending your file memset(buffer, 0, sizeof(buffer)); len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout reading DATA response"); } else { LOG(LOG_WARNING, "read: %m"); } return 0; } if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer); if (buffer[0] != '+') { LOG(LOG_WARNING, buffer); return 0; } if ((in = fopen(td->filename, "r")) == NULL) { LOG(LOG_ERR, "can't open %s", td->filename); return 0; } uw_setproctitle("%s:%d: UPLOADING, size=%u %s", q->host, q->port, filesize, td->filename); while ((i = fread(buffer, 1, sizeof(buffer), in)) == sizeof(buffer)) { //LOG(LOG_DEBUG, "read %d from input", i); len = st_write(rmt_nfd, buffer, i, TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout writing %s", buffer); } else { LOG(LOG_WARNING, "write: %m"); } fclose(in); return 0; } //LOG(LOG_DEBUG, "written %d to output", len); } if (!feof(in)) { LOG(LOG_ERR, "fread: %m"); fclose(in); return 0; } if (i>0 && st_write(rmt_nfd, buffer, i, TIMEOUT) != i) { LOG(LOG_ERR, "socket write error: %m"); fclose(in); return 0; } fclose(in); // expect here: +OK Thank you. Enter command memset(buffer, 0, sizeof(buffer)); len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout reading enter command"); } else { LOG(LOG_WARNING, "read: %m"); } return 0; } if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer); if (buffer[0] != '+') { LOG(LOG_WARNING, buffer); return 0; } sprintf(buffer, "QUIT\n"); uw_setproctitle("%s:%d %s", q->host, q->port, buffer); if (debug > 3) fprintf(stderr, "%s[%u] > %s", q->host, st_netfd_fileno(rmt_nfd), buffer); len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout writing %s", buffer); } else { LOG(LOG_WARNING, "write: %m"); } return 0; } // expect here: +OK Nice talking to you. Bye memset(buffer, 0, sizeof(buffer)); len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT); if (len == -1) { if (errno == ETIME) { LOG(LOG_WARNING, "timeout reading QUIT response", buffer); } else { LOG(LOG_WARNING, "read: %m"); } return 0; } if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer); return 1; }