예제 #1
0
void _RtmpServer::run()
{
  RTMP_LogSetLevel(RTMP_LOGDEBUG);

  INFO("RTMP server started (%s:%i)\n",
       inet_ntoa(SAv4(&listen_addr)->sin_addr),
       ntohs(SAv4(&listen_addr)->sin_port));

  while(fds_num){
    int ret = poll(fds,fds_num,500/*ms*/);
    if(ret == 0){
      continue;
    }

    if(ret<0){
      switch(errno){
      case EAGAIN:
      case EINTR:
	continue;
      default:
	ERROR("poll() failed: %s\n",strerror(errno));
	return;
      }
    }

    for(unsigned int i=0; i<fds_num; i++){
      if(fds[i].revents != 0){
	if(i == 0){
	  if(fds[i].revents & POLLIN){
	    struct sockaddr_in remote_addr;
	    socklen_t remote_addr_len = sizeof(remote_addr);
	    int new_fd = accept(fds[i].fd,(struct sockaddr*)&remote_addr,
				&remote_addr_len);
	    if(new_fd < 0){
	      ERROR("accept() failed: %s\n",strerror(errno));
	      continue;
	    }
	    RtmpConnection * conn = new RtmpConnection(new_fd);
	    conn->start();
	  } else {
	    // POLLERR or POLLHUP
	    ERROR("on socket %i",fds[i].fd);
	    close(fds[i].fd);
	    if(fds_num != 1){
	      fds[i] = fds[fds_num-1];
	    }
	    memset(&(fds[fds_num-1]),0,sizeof(struct pollfd));
	    fds_num--;
	  }
	}
      }
    }
  }

  INFO("RTMP event loop finished/n");
}
예제 #2
0
int _RtmpServer::listen(const char* addr, unsigned short port)
{
  int listen_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  if(listen_fd < 0){
    ERROR("socket() failed: %s\n",strerror(errno));
    return -1;
  }
  int onoff=1;
  if(setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&onoff,sizeof(onoff))<0){
    ERROR("setsockopt(...,SO_REUSEADDR,...) failed: %s\n",strerror(errno));
    close(listen_fd);
    return -1;
  }

  memset(&listen_addr,0,sizeof(listen_addr));

  listen_addr.ss_family = AF_INET;
#if defined(BSD44SOCKETS)
  listen_addr.ss_len = sizeof(struct sockaddr_in);
#endif
  SAv4(&listen_addr)->sin_port = htons(port);

  if(inet_aton(addr,&SAv4(&listen_addr)->sin_addr)<0){
	
    ERROR("inet_aton: %s\n",strerror(errno));
    return -1;
  }

  if(bind(listen_fd,(const sockaddr*)&listen_addr,sizeof(struct sockaddr_in)) < 0){
    ERROR("bind() failed: %s\n",strerror(errno));
    close(listen_fd);
    return -1;
  }

  if(::listen(listen_fd,CONN_BACKLOG)<0){
    ERROR("listen() failed: %s\n",strerror(errno));
    close(listen_fd);
    return -1;
  }

  fds[0].fd = listen_fd;
  fds[0].events = POLLIN | POLLERR;
  fds_num++;

  return 0;
}
예제 #3
0
/** @see transport */
int udp_trsp::bind(const string& address, unsigned short port)
{
    if(sd){
	WARN("re-binding socket\n");
	close(sd);
    }
    
    memset(&local_addr,0,sizeof(local_addr));
    local_addr.ss_family = AF_INET;
#if defined(BSD44SOCKETS)
    local_addr.ss_len = sizeof(struct sockaddr_in);
#endif
    SAv4(&local_addr)->sin_port = htons(port);

    if(inet_aton(address.c_str(),&SAv4(&local_addr)->sin_addr)<0){
	
	ERROR("inet_aton: %s\n",strerror(errno));
	return -1;
    }

    if(SAv4(&local_addr)->sin_addr.s_addr == INADDR_ANY){
	ERROR("Sorry, we cannot bind 'ANY' address\n");
	return -1;
    }

    if((sd = socket(PF_INET,SOCK_DGRAM,0)) == -1){
	ERROR("socket: %s\n",strerror(errno));
	return -1;
    } 
    

    if(::bind(sd,(const struct sockaddr*)&local_addr,
	     sizeof(struct sockaddr_in))) {

	ERROR("bind: %s\n",strerror(errno));
	close(sd);
	return -1;
    }
    
    int true_opt = 1;
    if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
		  (void*)&true_opt, sizeof (true_opt)) == -1) {
	
	ERROR("%s\n",strerror(errno));
	close(sd);
	return -1;
    }

    if(setsockopt(sd, IPPROTO_IP, DSTADDR_SOCKOPT,
		  (void*)&true_opt, sizeof (true_opt)) == -1) {
	
	ERROR("%s\n",strerror(errno));
	close(sd);
	return -1;
    }

    local_port = port;
    local_ip   = address;

    DBG("UDP transport bound to %s:%i\n",address.c_str(),port);

    return 0;
}
예제 #4
0
/** @see trsp_socket */
int udp_trsp_socket::bind(const string& bind_ip, unsigned short bind_port)
{
    if(sd){
	WARN("re-binding socket\n");
	close(sd);
    }
    
    memset(&addr,0,sizeof(addr));

    addr.ss_family = AF_INET;
#if defined(BSD44SOCKETS)
    addr.ss_len = sizeof(struct sockaddr_in);
#endif
    SAv4(&addr)->sin_port = htons(bind_port);

    if(inet_aton(bind_ip.c_str(),&SAv4(&addr)->sin_addr)<0){
	
	ERROR("inet_aton: %s\n",strerror(errno));
	return -1;
    }

    if(SAv4(&addr)->sin_addr.s_addr == INADDR_ANY){
	ERROR("Sorry, we cannot bind 'ANY' address\n");
	return -1;
    }

    if((sd = socket(PF_INET,SOCK_DGRAM,0)) == -1){
	ERROR("socket: %s\n",strerror(errno));
	return -1;
    } 
    

    if(::bind(sd,(const struct sockaddr*)&addr,
	     sizeof(struct sockaddr_in))) {

	ERROR("bind: %s\n",strerror(errno));
	close(sd);
	return -1;
    }
    
    int true_opt = 1;
    if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
		  (void*)&true_opt, sizeof (true_opt)) == -1) {
	
	ERROR("%s\n",strerror(errno));
	close(sd);
	return -1;
    }

    if(setsockopt(sd, IPPROTO_IP, DSTADDR_SOCKOPT,
		  (void*)&true_opt, sizeof (true_opt)) == -1) {
	
	ERROR("%s\n",strerror(errno));
	close(sd);
	return -1;
    }

    if (SipCtrlInterface::udp_rcvbuf > 0) {
	DBG("trying to set SIP UDP socket buffer to %d\n",
	    SipCtrlInterface::udp_rcvbuf);
	if(setsockopt(sd, SOL_SOCKET, SO_RCVBUF,
		      (void*)&SipCtrlInterface::udp_rcvbuf,
		      sizeof (SipCtrlInterface::udp_rcvbuf)) == -1) {
	    WARN("could not set SIP UDP socket buffer: '%s'\n",
		 strerror(errno));
	} else {
	    socklen_t optlen;
	    int set_rcvbuf_size=0;
	    if (getsockopt(sd, SOL_SOCKET, SO_RCVBUF,
			   &set_rcvbuf_size, &optlen) == -1) {
		WARN("could not read back SIP UDP socket buffer length: '%s'\n",
		     strerror(errno));
	    } else {
		if (set_rcvbuf_size != SipCtrlInterface::udp_rcvbuf) {
		    WARN("failed to set SIP UDP RCVBUF size (wanted %d, got %d)\n",
			 SipCtrlInterface::udp_rcvbuf, set_rcvbuf_size);
		}
	    }
	}
    }

    port = bind_port;
    ip   = bind_ip;

    DBG("UDP transport bound to %s:%i\n",ip.c_str(),port);

    return 0;
}