コード例 #1
0
ファイル: linux-test.c プロジェクト: 32bitmicro/riscv-qemu
void test_socket(void)
{
    int server_fd, client_fd, fd, pid, ret, val;
    struct sockaddr_in sockaddr;
    socklen_t len;
    char buf[512];

    server_fd = server_socket();

    /* test a few socket options */
    len = sizeof(val);
    chk_error(getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &val, &len));
    if (val != SOCK_STREAM)
        error("getsockopt");

    pid = chk_error(fork());
    if (pid == 0) {
        client_fd = client_socket();
        send(client_fd, socket_msg, sizeof(socket_msg), 0);
        close(client_fd);
        exit(0);
    }
    len = sizeof(sockaddr);
    fd = chk_error(accept(server_fd, (struct sockaddr *)&sockaddr, &len));

    ret = chk_error(recv(fd, buf, sizeof(buf), 0));
    if (ret != sizeof(socket_msg))
        error("recv");
    if (memcmp(buf, socket_msg, sizeof(socket_msg)) != 0)
        error("socket_msg");
    chk_error(close(fd));
    chk_error(close(server_fd));
}
コード例 #2
0
ファイル: mc_init.c プロジェクト: ZZMarquis/LLServer
void start_mc_server()
{
	/* create the listening socket and bind it */
    if (settings.socketpath == NULL) {
        l_socket = server_socket(settings.port, 0);
        if (l_socket == -1) {
            fprintf(stderr, "failed to listen\n");
            exit(EXIT_FAILURE);
        }
    }

	/* initialize main thread libevent instance */
    main_base = event_init();
	/* create the initial listening connection */
    /*if (!(listen_conn = conn_new(l_socket, conn_listening,
                                 EV_READ | EV_PERSIST, 1, false, main_base))) {
        fprintf(stderr, "failed to create listening connection");
        exit(EXIT_FAILURE);
    }*/

	struct event ev;
	event_set(&ev, l_socket, EV_READ | EV_PERSIST, event_handler, (void *)&l_socket);	//函数创建新的事件结构
    event_base_set(main_base, &ev);
	//event_add使通过event_set()设置的事件在事件匹配或超时时(如果设置了超时)被执行
	if (event_add(&ev, 0) == -1) {
		//close(l_socket);
	}

	thread_init(settings.num_threads, main_base);/* llthread.c */
    /* enter the event loop */
    event_base_loop(main_base, 0);    
}
コード例 #3
0
int try_open_new_listening_sockets (struct mc_config *MC) {
  int i, j, sfd;
  for (i = 0; i < MC->clusters_num; i++) {
    if (MC->Clusters[i].other_cluster_no >= 0) {
      continue;
    }
    sfd = server_socket (MC->Clusters[i].port, settings_addr, backlog, 0);
    if (sfd >= MAX_CONNECTIONS) {
      vkprintf (0, "cannot open server socket at port %d: too many open connections (fd=%d)\n", MC->Clusters[i].port, sfd);
      close (sfd);
      sfd = -1;
    }
    if (sfd < 0) {
      vkprintf (0, "cannot open server socket at port %d: %m\n", MC->Clusters[i].port);
      for (j = 0; j < i; j++) {
	if (MC->Clusters[j].other_cluster_no < 0) {
	  sfd = MC->Clusters[j].server_socket;
	  close (sfd);
	  MC->Clusters[j].server_socket = -1;
	  vkprintf (1, "closed newly-opened listening socket at %s:%d, fd=%d\n", conv_addr (settings_addr.s_addr, 0), MC->Clusters[j].port, sfd);
	}
      }
      return -2;
    }
    vkprintf (1, "created listening socket at %s:%d, fd=%d\n", conv_addr (settings_addr.s_addr, 0), MC->Clusters[i].port, sfd);
    MC->Clusters[i].server_socket = sfd;
  }
  return 0;
}
コード例 #4
0
ファイル: threadsay.c プロジェクト: wadee/go_proj
int main(int argc, char** argv){    
    /*
        主线程主体流程:
        conn_init;
        thread_init;
        还得有一个
        stat_init
        stats的结构是用来记录当前的状态的,stats是一个静态变量
    
        server_socket 请求,分发
        注册事件loop
    */
    int retval;
    main_base = event_init();
    FILE *portnumber_file = NULL;
    portnumber_file = fopen("/tmp/portnumber.file", "a");

    stats_init();
    conn_init();
    thread_init(NUM_OF_THREADS);

    server_socket("127.0.0.1", SERVER_PORT, tcp_transport, portnumber_file);

    if (event_base_loop(main_base, 0) != 0) {
	printf("event_base_loop error");
        retval = EXIT_FAILURE;
    }
    return retval;

    exit(0);

}
コード例 #5
0
int main (int argc, char** argv) {

	pthread_t thread;
	int listener, nuevaConexion;

	/* Creación de archivo log */
	Logger = log_create(LOG_PATH, "MSP", false, LOG_LEVEL_TRACE);
	clean_file(LOG_PATH);

	cargarConfiguracion(argv[1]);
	inicializarMSP();

	log_trace(Logger, "Inicio de MSP.\n	Tamaño de Memoria Principal: %u.\n	Tamaño de SWAP: %u.", MaxMem, MaxSwap);

	listener = server_socket(Puerto);
	pthread_create(&thread, NULL, atenderConsola, NULL);

	while (true) {

		nuevaConexion = accept_connection(listener);

		pthread_mutex_lock(&LogMutex);
		log_trace(Logger, "Nueva conexión.");
		pthread_mutex_unlock(&LogMutex);

		pthread_create(&thread, NULL, atenderProceso, &nuevaConexion);
	}

	return EXIT_SUCCESS;

}
コード例 #6
0
int main(int argc, char *argv[]){
  int soc;

  if(argc <= 1){
    fprintf(stderr, "server port\n");
    return(EX_USAGE);
  }

  if(argc >= 3 && argv[2][0] == 'n'){
    fprintf(stderr, "Nonblocking mode\n");
    g_mode = 'n';
  } else {
    g_mode = 'b';
  }
  
  if((soc = server_socket(argv[1])) == -1){
    fprintf(stderr, "server_socket(%s):error\n", argv[1]);
    return(EX_UNAVAILABLE);
  }
  fprintf(stderr, "ready for accept\n");
  
  accept_loop(soc);

  close(soc);
  return(EX_OK);
}
コード例 #7
0
Tunnel * tunnel_new_server (int port )
{
	Tunnel *tunnel;
	tunnel = ( Tunnel *) malloc (sizeof (Tunnel ));
	if ( tunnel == NULL )
		return NULL ;
	//if ( content_length == 0 )
		//content_length = DEFAULT_CONTENT_LENGTH;
	tunnel->in_fd = INVALID_SOCKET;
	tunnel->out_fd = INVALID_SOCKET;
	tunnel->server_socket = INVALID_SOCKET;
	tunnel->dest.host_name = NULL;
	tunnel->dest.host_port = port;
	tunnel->buf_ptr = tunnel->buf;
	tunnel->buf_len = 0;
	
	tunnel->content_length = DEFAULT_CONTENT_LENGTH - 1;
	/*
	tunnel->in_total_raw = 0;
	tunnel->in_total_data = 0;
	tunnel->out_total_raw = 0;
	tunnel->out_total_data = 0;
	*/
	tunnel->strict_content_length=FALSE;
	tunnel->bytes = 0;
	
	tunnel->server_socket = server_socket (port);

	if ( tunnel->server_socket == INVALID_SOCKET)
		return NULL;
	return tunnel;
}
コード例 #8
0
ファイル: server.c プロジェクト: luozengbin/linuxnet
int
main(int argc, char *argv[])
{
    int soc;
    /* 引数にポート番号が指定されているか? */
    if (argc <= 1) {
        (void) fprintf(stderr,"server port\n");
        return (EX_USAGE);
    }
    /* サーバソケットの準備 */
    if ((soc = server_socket(argv[1])) == -1) {
        (void) fprintf(stderr,"server_socket(%s):error\n", argv[1]);
        return (EX_UNAVAILABLE);
    }
    (void) fprintf(stdout, "ready for accept\n");
    /* アクセプトループ */
    accept_loop(soc);

    /* for (;;) { */
    /*     (void) fprintf(stdout, "just sleep\n"); */
    /*     sleep(5); */
    /* } */

    /* ソケットクローズ */
    (void) close(soc);
    return (EX_OK);
}
コード例 #9
0
void ServerController::start_server()
{
	is_server_running = true;

	// Create thread for consuming process
	std::thread consumer_thread(&ServerController::consume_command, this);
	consumer_thread.detach();

	//Create server socket
	ServerSocket server_socket(port_number);

	while (true)
	{
		try
		{
			std::cerr << "Server listening" << "\n";
			std::shared_ptr<Socket> socket_client = nullptr;

			while ((socket_client = server_socket.accept()) != nullptr)
			{
				std::thread handler_thread(&ServerController::handle_client, this, socket_client);
				handler_thread.detach();
				std::cerr << "Server listening again" << "\n";
			}
		}
		catch (const std::exception& ex)
		{
			std::cerr << ex.what() << ", resuming..." << "\n";
		}
	}
}
コード例 #10
0
ファイル: net_http_server.hpp プロジェクト: quepas/Stormy
int HttpServer<ServerContext, RequestFactory>::main(const std::vector<std::string>& args)
{
  Poco::Net::ServerSocket server_socket(config().getInt("Service.port", port_));
  Poco::Net::HTTPServer http_server(
    new RequestFactory(context_),
    server_socket,
    new Poco::Net::HTTPServerParams);
  http_server.start();
  waitForTerminationRequest();
  http_server.stop();
  return Poco::Util::Application::EXIT_OK;
}
コード例 #11
0
int ctl_socket_init(void)
{
    int s = server_socket();
    if (s < 0)
        return -1;

    ctl_handler.fd = s;
    ctl_handler.handler = ctl_rcv_handler;

    TST(add_epoll(&ctl_handler) == 0, -1);
    return 0;
}
コード例 #12
0
int
start_server()
{
	int soc;
	if ((soc = server_socket(PORT)) == -1) {
		(void) fprintf(stderr, "server_socket(%s):error\n", PORT);
		return (EX_UNAVAILABLE);
	}
	(void) fprintf(stderr, "ready for accept\n");
	accept_loop(soc);
	(void) close(soc);
	return 0;
}
コード例 #13
0
void engine_init (engine_t *E, const char *const pwd_filename, int index_mode) {
  E->sfd = 0;
  struct sigaction sa;
  memset (&sa, 0, sizeof (sa));
  sa.sa_handler = sigusr1_handler;
  sigemptyset (&sa.sa_mask);
  sigaction (SIGUSR1, &sa, NULL);
  sa.sa_handler = sigrtmax_handler;
  sigaction (SIGRTMAX, &sa, NULL);

  if (!index_mode && port < PRIVILEGED_TCP_PORTS) {
    E->sfd = server_socket (port, E->settings_addr, backlog, 0);
    if (E->sfd < 0) {
      kprintf ("cannot open server socket at port %d: %m\n", port);
      exit (1);
    }
  }

  const int gap = 16;
  if (getuid ()) {
    struct rlimit rlim;
    if (getrlimit (RLIMIT_NOFILE, &rlim) < 0) {
      kprintf ("%s: getrlimit (RLIMIT_NOFILE) fail. %m\n", __func__);
      exit (1);
    }
    if (maxconn > rlim.rlim_cur - gap) {
      maxconn = rlim.rlim_cur - gap;
    }
  } else {
    if (raise_file_rlimit (maxconn + gap) < 0) {
      kprintf ("fatal: cannot raise open file limit to %d\n", maxconn + gap);
      exit (1);
    }
  }

  aes_load_pwd_file (pwd_filename);
  
  if (change_user (username) < 0) {
    kprintf ("fatal: cannot change user to %s\n", username ? username : "******");
    exit (1);
  }

  init_dyn_data ();
  if (udp_enabled) {
    init_server_PID (get_my_ipv4 (), port);
  }
}
コード例 #14
0
ファイル: re-exec.c プロジェクト: luozengbin/linuxnet
int
main(int argc, char *argv[], char *envp[])
{

    struct sigaction sa;
    int soc;
    /* 引数にポート番号が指定されているか? */
    if (argc <= 1) {
        (void) fprintf(stderr,"re-exec port\n");
        return (EX_USAGE);
    }

    if (argc == 3) {
        (void) fprintf(stderr,"skip daemonize\n");
    } else {
        /* デーモン化 */
        (void) daemonize(0, 0);
    }

    /* コマンドライン引数、環境変数のアドレスをグローバルに保持 */
    argc_ = &argc;
    argv_ = &argv;
    envp_ = &envp;
    /* SIGHUPのシグナルハンドラを指定 */
    (void) sigaction(SIGHUP, (struct sigaction *) NULL, &sa);
    sa.sa_handler = sig_hangup_handler;
    sa.sa_flags = SA_NODEFER;
    (void) sigaction(SIGHUP, &sa, (struct sigaction *) NULL);
    (void) fprintf(stderr, "sigaction():end\n");
    /* サーバソケットの準備 */
    if ((soc = server_socket(argv[1])) == -1) {
        (void) fprintf(stderr,"server_socket(%s):error\n", argv[1]);
        return (EX_UNAVAILABLE);
    }
    (void) fprintf(stderr, "ready for accept\n");
    /* アクセプトループ */
    accept_loop(soc);
    /* ソケットクローズ */
    (void) close(soc);
    return (EX_OK);
}
コード例 #15
0
int server()
{
    char buffer[1024];
    int ss = server_socket("127.0.0.1", "9991");
    if (ss < 0) {
        logging(LOG_ERROR, "socket error!");
        return -1;
    }
    int ns = tcptoaccept(ss, 100000);
    if (ns < 0) {
        logging(LOG_ERROR, "accept error!");
        return -1;
    }
    tcpnonblock(ns);
    tcpnodelay(ns);
    tcptoread(ns, buffer, 10, 3000);
    /*printf("read ok %d !!\n", n); */
    /*printf("read data: \n%s\n", buffer); */
    assert(strcmp("helloworl", buffer) == 0);
    tcpclose(ns);
    tcpclose(ss);
    return 0;
}
コード例 #16
0
ファイル: server.cpp プロジェクト: rghorbani/network-ca1
void SG_Server::init(char* args[]) {
	/*
	struct sigaction sa;

	struct addrinfo hints, *servinfo, *p;
    
	memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    int truVal = 1;
    int status = 0;
    
    while((status = getaddrinfo(NULL, args[1], &hints, &servinfo)) != 0 ) {
    	errx(-1, "%s",gai_strerror(status));
    }
    
    for(p = servinfo; p != NULL; p = p->ai_next) {
    	if (((sockfd) = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
    		continue;
    	}
        
    	if ((status = setsockopt((sockfd), SOL_SOCKET, SO_REUSEADDR, &truVal, sizeof(int))) == -1) {
    		errx(-2, "%s",gai_strerror(status));
    	}
        
    	if (bind((sockfd), p->ai_addr, p->ai_addrlen) == -1) {
    		close((sockfd));
    		continue;
    	}
    	break;
    }
    
    if (p == NULL)  {
    	errx(-3, "%s", "Initialization failed\n");
    }
    
    //Start listening
  	if (listen(sockfd, BACKLOG) == -1) {
    	perror("Listen error");
        errx(-4, "%s", "Listening Failed\n");
    }
    //(sa).sa_handler = sigchld_handler(0); // reap all dead processes
    sigemptyset(&((sa).sa_mask));
    (sa).sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, NULL, &sa) == -1) {
    	errx(-5, "%s", "Handler Failed\n");
    }

    cerr << "[INIT] Server Initilized on port " << port << endl;

    int maxSocket = listener;

    FD_SET(listener, &safeSet);
    FD_SET(0, &safeSet);

    cerr << "[INIT] Server is up and runnig...\n\n";
    */

    ServerSocket server_socket ( 30000 );
    server = server_socket;
}
コード例 #17
0
void start_server (void) {
  char buf[64];
  int i, prev_time = 0;

  init_epoll ();
  init_netbuffers ();

  if (!sfd) {
    sfd = server_socket (port, settings_addr, backlog, 0);
  }

  if (sfd < 0) {
    kprintf ("cannot open server socket at port %d: %m\n", port);
    exit (3);
  }

  vkprintf (1, "created listening socket at %s:%d, fd=%d\n", conv_addr (settings_addr.s_addr, buf), port, sfd);

  if (daemonize) {
    setsid ();
  }

  if (change_user (username) < 0) {
    kprintf ("fatal: cannot change user to %s\n", username ? username : "******");
    exit (1);
  }

  if (binlogname && !binlog_disabled) {
    assert (append_to_binlog (Binlog) == log_readto_pos);
  }

  init_listening_connection (sfd, &ct_rpc_server, &copyexec_result_rpc_server);

  sigset_t signal_set;
  sigemptyset (&signal_set);
  sigaddset (&signal_set, SIGINT);
  sigaddset (&signal_set, SIGTERM);
  sigaddset (&signal_set, SIGUSR1);
  if (daemonize) {
    sigaddset (&signal_set, SIGHUP);
  }
  struct sigaction act;
  act.sa_handler = copyexec_results_sig_handler;
  act.sa_mask = signal_set;
  act.sa_flags = 0;
  for (i = 1; i <= SIGRTMAX; i++) {
    if (sigismember (&signal_set, i)) {
      if (sigaction (i, &act, NULL) < 0) {
        kprintf ("sigaction (%d) failed. %m\n", i);
        exit (1);
      }
    }
  }

  for (i = 0; ; i++) {
    if (!(i & 255)) {
      vkprintf (1, "epoll_work(): %d out of %d connections, network buffers: %d used, %d out of %d allocated\n",
	       active_connections, maxconn, NB_used, NB_alloc, NB_max);
    }
    epoll_work (71);

    if (interrupted_by_term_signal ()) {
      break;
    }

    if (pending_signals & (1LL << SIGHUP)) {
      pending_signals_clear_bit (&signal_set, SIGHUP);
      kprintf ("got SIGHUP.\n");
      sync_binlog (2);
    }

    if (pending_signals & (1LL << SIGUSR1)) {
      pending_signals_clear_bit (&signal_set, SIGUSR1);
      kprintf ("got SIGUSR1, rotate logs.\n");
      reopen_logs ();
      sync_binlog (2);
    }

    if (now != prev_time) {
      prev_time = now;
      cron ();
    }
    if (quit_steps && !--quit_steps) break;
  }

  epoll_close (sfd);
  close (sfd);

  flush_binlog_last ();
  sync_binlog (2);
}
コード例 #18
0
ファイル: server.c プロジェクト: penguintoku/College
int main(int argc, char *argv[]){

	//Check if valid format
	if(argc != 4){
		printf("\n\nUsage: ./server <certificate> <key> <port number>\n\n");
		exit(1);
	}

	//Initialization
	SSL_CTX *ctx;
	int server;
	char *port;
	SSL_library_init();

	//Get the port from the argument
	port = argv[3];

	//Initialize the OpenSSL (page 1)
	ctx = initialize_server();

	//Load and validate the certificate and key (page 1)
	if(SSL_CTX_use_certificate_file(ctx, argv[1], SSL_FILETYPE_PEM) <= 0){
		printf("\n\nERROR: SSL_CTX_use_certificate_file failed (server.c - main)\n");
		printf("Could not find the certificate file.\n\n");
		exit(1);
	}
	if(SSL_CTX_use_PrivateKey_file(ctx,  argv[2], SSL_FILETYPE_PEM) <= 0){
		printf("\n\nERROR: SSL_CTX_use_PrivateKey_file failed (server.c - main)\n");
		printf("Could not find the private key file or incorrect key.\n\n");
		exit(1);
	}
	if(!SSL_CTX_check_private_key(ctx)){
		printf("\n\nERROR: SSL_CTX_check_private_key failed (server.c -main)\n");
		printf("Private key does not match the public certificate\n\n");
		exit(1);
	}	

	//create server socket
	server = server_socket(atoi(port));	

	//Continue listening
	while(1){
		struct sockaddr_in addr;
		socklen_t addrLen = sizeof(addr);
		SSL *ssl;

		//If client connects
		int client = accept(server, (struct sockaddr*) &addr, &addrLen);
		if(client < 0){
			printf("\n\nERROR: accept() failed (server.c - main).\n\n");
			printf("Couldn't create socket.\n\n");
			exit(1);
		}

		//creates a new SSL structure to hold the data for SSL connection
		ssl = SSL_new(ctx);
		if(ssl == NULL){
			printf("\n\nERROR: SSL_new() failed (server.c - main).\n\n");
			printf("Couldn't create new SSL structure.\n\n");
			exit(1);
		}

		//Sets the file descriptor client as the input/output facility for the SSL (encrypted) side of ssl
		SSL_set_fd(ssl, client);

		//Start talking
		ssl_handshake(ssl);	
	}

	//close and exit
	close(server);	
	SSL_CTX_free(ctx);
	return 0;
}
コード例 #19
0
ファイル: server.c プロジェクト: gitorup/HTTP2RTSP
int start_server(const char *url, const char *rtspport)
{
  int mediafd = -1, listenfd, tempfd, maxfd;
  int videofd;
  struct addrinfo *info;
  struct sockaddr_storage remoteaddr;
  socklen_t addrlen = sizeof remoteaddr;
  fd_set readfds, masterfds;
  struct timeval *timeout, *timeind = NULL, timenow;
  int nready, i;
  int videosize, videoleft;
  int recvd, sent;
  char urlhost[URLSIZE], urlpath[URLSIZE], tempstr[URLSIZE];
  unsigned char msgbuf[BUFSIZE], sendbuf[BUFSIZE];
  char *temp;
  unsigned char *sps = NULL, *pps = NULL;
  size_t spslen, ppslen;
  RTSPMsg rtspmsg;
  Client streamclient;
  pthread_t threadid;
  ThreadInfo *tinfo = NULL;

  uint16_t rtpseqno_video = (rand() % 1000000);
  uint16_t rtpseqno_audio = (rand() % 1000000);

  TimeoutEvent *event;

  /* The current state of the protocol */
  int mediastate = IDLE;
  int quit = 0;

  int media_downloaded = 0;

  timeout = (struct timeval *)malloc(sizeof(struct timeval));
  init_client(&streamclient);
  

  /* Open the a file where the video is to be stored */
  if ((videofd = open("videotemp.mp4", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
    fatal_error("Error opening the temporary videofile");
  }

  /* Create the RTSP listening socket */
  resolve_host(NULL, rtspport, SOCK_STREAM, AI_PASSIVE, &info);
  listenfd = server_socket(info);
  maxfd = listenfd;


  FD_ZERO(&readfds);
  FD_ZERO(&masterfds);
  FD_SET(listenfd, &masterfds);

  while (!quit) {

    readfds = masterfds;

    if ((nready = Select(maxfd + 1, &readfds, timeind)) == -1) {
      printf("Select interrupted by a signal\n");
    } 

    /* Timeout handling, used for packet pacing and other timeouts */
    else if (nready == 0) {
      timeind = NULL;
      lock_mutex(&queuelock);
      if ((event = pull_event(&queue)) != NULL) {

        switch (event->type) {

	case ENDOFSTREAM:
	  printf("MEDIA FINISHED\n");
	  break;

	case FRAME:
	  /* Video frame */
	  if (event->frame->frametype == VIDEO_FRAME) {
	    rtpseqno_video += send_video_frame(sendbuf, event->frame, streamclient.videofds[0], rtpseqno_video);
	  }

	  /* Audio frame */
	  else {
            rtpseqno_audio += send_audio_frame(sendbuf, event->frame, streamclient.audiofds[0], rtpseqno_audio);
	  }

          free(event->frame->data);
          free(event->frame);
          break;

	case CHECKMEDIASTATE:
	  oma_debug_print("Checking media ready for streaming...\n");
	  if (mediastate != STREAM) {
	    printf("Sending dummy RTP\n");
	    send_dummy_rtp(sendbuf, streamclient.videofds[0], &rtpseqno_video);
	    push_timeout(&queue, 1000, CHECKMEDIASTATE);
	  }
          break;

	default:
	  oma_debug_print("ERRORENOUS EVENT TYPE!\n");
          break;
        }

        /* If there are elements left in the queue, calculate next timeout */
        if (queue.size > 0) {
          *timeout = calculate_delta(&event->time, &queue.first->time);
          timeind = timeout;
          oma_debug_print("Timeout: %ld secs, %ld usecs\n", timeout->tv_sec, timeout->tv_usec);
        }
        else {
          oma_debug_print("The first entry of the queue is NULL!\n");
        }

        if (queue.size < QUEUESIZE / 2) {
          oma_debug_print("Signaling thread to start filling the queue");
          pthread_cond_signal(&queuecond);
        }

        free(event);
      }

      unlock_mutex(&queuelock);
      continue;
    } /* End of timeout handling */

    /* Start to loop through the file descriptors */
    for (i = 0; i <= maxfd; i++) {
      if (FD_ISSET(i, &readfds)) {

        nready--;

        /* New connection from a client */
        if (i == listenfd) {
          oma_debug_print("Recieved a new RTSP connection\n");
	  fflush(stdout);
          if ((tempfd = accept(i, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) {
            if (errno != EWOULDBLOCK && errno != ECONNABORTED &&
                errno != EPROTO && errno != EINTR) {
              fatal_error("accept");
            }
          }

          /* If we are already serving a client, close the new connection. Otherwise, continue. */
          if (streamclient.state != NOCLIENT) {
	    printf("Another RTSP client tried to connect. Sorry, we can only serve one client at a time\n");
	    close (tempfd);
	  }
          else {
            streamclient.rtspfd = tempfd;
            streamclient.state = CLICONNECTED;
            maxfd = max(2, streamclient.rtspfd, maxfd);
            FD_SET(streamclient.rtspfd, &masterfds);
	    }
        }

        /* Data from the media source */
        else if (i == mediafd) {

          switch (mediastate) {

            case GETSENT:
              /* Read ONLY the HTTP message from the socket and store the video size */
              recvd = recv_all(i, msgbuf, BUFSIZE, MSG_PEEK);
              temp = strstr((char *)msgbuf, "\r\n\r\n");
              recvd = recv_all(i, msgbuf, (int)(temp + 4 - (char *)msgbuf), 0);
              printf("Received HTTP response\n%s\n", msgbuf);
              temp = strstr((char *)msgbuf, "Content-Length:");
              sscanf(temp, "Content-Length: %d", &videosize);
              videoleft = videosize;
              mediastate = RECVTCP;
              break;

            case RECVTCP:
              if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) {
                FD_CLR(i, &masterfds);
                close(i);
                oma_debug_print("Socket closed\n");
              }
              oma_debug_print("Received data from video source!\n");

              writestr(videofd, msgbuf, recvd);
              videoleft -= recvd;

              if (videoleft <= 0) {
                
		printf("Video download complete.\n");
                FD_CLR(mediafd, &masterfds);
                close(videofd);
                close(mediafd);
		media_downloaded = 1;
		printf("Media socket closed\n");

                /* Create the context and the queue filler thread parameter struct */
                tinfo = (ThreadInfo *)malloc(sizeof(ThreadInfo));
                initialize_context(&tinfo->ctx, "videotemp.mp4", &tinfo->videoIdx, &tinfo->audioIdx,
                    &tinfo->videoRate, &tinfo->audioRate, &sps, &spslen, &pps, &ppslen);

                /* Launch the queue filler thread */
                CHECK((pthread_create(&threadid, NULL, fill_queue, tinfo)) == 0);
                pthread_detach(threadid);

                /* Send the sprop-parameters before any other frames */
                send_video_frame(sendbuf, create_sprop_frame(sps, spslen, 0),
                    streamclient.videofds[0], rtpseqno_video++);
                send_video_frame(sendbuf, create_sprop_frame(pps, ppslen, 0),
                    streamclient.videofds[0], rtpseqno_video++);

                g_free(sps);
                g_free(pps);

                lock_mutex(&queuelock);
                push_timeout(&queue, 1000, CHECKMEDIASTATE);
                unlock_mutex(&queuelock);

                mediastate = STREAM;
              }
              break;

             case STREAM:
              /*
                 close(videofd);
                 close(mediafd);
                 close(listenfd);
                 quit = 1;
                 */
              break;

            default: 
              break;
          }
        }

        /* Data from a client ( i == streamclient.rtspfd) */
        else {

          oma_debug_print("Received data from rtspfd\n");
	  fflush(stdout);

          if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) {
            FD_CLR(i, &masterfds);
            close(i);
            oma_debug_print("RTSP client closed the connection\n");
            streamclient.state = NOCLIENT;
          }
          else {
            oma_debug_print("%s", msgbuf);
            parse_rtsp(&rtspmsg, msgbuf);
          }

	  if (rtspmsg.type == TEARDOWN) {

            /* Kill thread and empty queue */         
 	    lock_mutex(&queuelock);
            pthread_cancel(threadid);
            empty_queue(&queue);
            sleep(1);
            

	    /* Reply with 200 OK */
            sent = rtsp_teardown(&rtspmsg, sendbuf);
            send_all(i, sendbuf, sent);
            FD_CLR(i, &masterfds);
            close(i);
            close(streamclient.videofds[0]);
            close(streamclient.videofds[1]);
            close(streamclient.audiofds[0]);
            close(streamclient.audiofds[1]);

            printf("Closing AVFormatContext\n");
            close_context(tinfo->ctx);
            free(tinfo);
            rtpseqno_video = (rand() % 1000000) + 7;
            rtpseqno_audio = rtpseqno_video + 9;
            init_client(&streamclient);

	    printf("Closing RTSP client sockets (RTP&RTCP)\n");
            streamclient.state = NOCLIENT;

	    unlock_mutex(&queuelock);
	    pthread_cond_signal(&queuecond);
          }

          switch (streamclient.state) {

            case CLICONNECTED:
              if (rtspmsg.type == OPTIONS) {
                sent = rtsp_options(&rtspmsg, &streamclient, sendbuf);
                send_all(i, sendbuf, sent);
              }
              else if (rtspmsg.type == DESCRIBE) {
		if (media_downloaded == 0) {
		  /* Start fetching the file from the server */
		  parse_url(url, urlhost, urlpath);
		  resolve_host(urlhost, "80", SOCK_STREAM, 0, &info);
		  mediafd = client_socket(info, 0);
		  FD_SET(mediafd, &masterfds);
		  maxfd = max(2, maxfd, mediafd);

		  /* Send the GET message */
		  http_get(url, msgbuf);
		  send_all(mediafd, msgbuf, strlen((char *)msgbuf));
		  mediastate = GETSENT;
		}
		else {
		  mediastate = STREAM;
		}

                /* Send the SDP without sprop-parameter-sets, those are sent
                 * later in-band */
                streamclient.state = SDPSENT;
                sent = rtsp_describe(&streamclient, sendbuf);
                send_all(i, sendbuf, sent);
              }
              break;

            case SDPSENT:
              if (rtspmsg.type == SETUP) {
                streamclient.setupsreceived++;

                /* Open up the needed ports and bind them locally. The RTCP ports opened here
                 * are not really used by this application. */
                write_remote_ip(tempstr, streamclient.rtspfd);
                oma_debug_print("Remote IP: %s\n", tempstr);

                if (streamclient.setupsreceived < 2) {
                  resolve_host(tempstr, rtspmsg.clirtpport, SOCK_DGRAM, 0, &info); 
                  streamclient.audiofds[0] = client_socket(info, streamclient.server_rtp_audio_port);
                  resolve_host(tempstr, rtspmsg.clirtcpport, SOCK_DGRAM, 0, &info);
                  streamclient.audiofds[1] = client_socket(info, streamclient.server_rtcp_audio_port);

                  sent = rtsp_setup(&rtspmsg, &streamclient, sendbuf,
                      streamclient.server_rtp_audio_port, streamclient.server_rtcp_audio_port);

                }
                else {
                  resolve_host(tempstr, rtspmsg.clirtpport, SOCK_DGRAM, 0, &info); 
                  streamclient.videofds[0] = client_socket(info, streamclient.server_rtp_video_port);
                  resolve_host(tempstr, rtspmsg.clirtcpport, SOCK_DGRAM, 0, &info);
                  streamclient.audiofds[1] = client_socket(info, streamclient.server_rtcp_video_port);

                  sent = rtsp_setup(&rtspmsg, &streamclient, sendbuf,
                      streamclient.server_rtp_video_port, streamclient.server_rtcp_video_port);

                streamclient.state = SETUPCOMPLETE;
                }

                oma_debug_print("Sending setup response...\n");
                send_all(i, sendbuf, sent);

              }
              break;

            case SETUPCOMPLETE:
              if (rtspmsg.type == PLAY) {

                /* Respond to the PLAY request, and start sending dummy RTP packets
                 * to disable the client timeout */
                sent = rtsp_play(&rtspmsg, sendbuf);
                send_all(i, sendbuf, sent);

		if (media_downloaded == 0) {
		 
		  lock_mutex(&queuelock);
		  push_timeout(&queue, 100, CHECKMEDIASTATE);
		  unlock_mutex(&queuelock);
		}
		/* Media has already been once downloaded, initialize context and thread */
		else {
		  tinfo = (ThreadInfo *)malloc(sizeof(ThreadInfo));
		  initialize_context(&tinfo->ctx, "videotemp.mp4", &tinfo->videoIdx, &tinfo->audioIdx,
				     &tinfo->videoRate, &tinfo->audioRate, &sps, &spslen, &pps, &ppslen);
		  /* Launch the queue filler thread */
		  CHECK((pthread_create(&threadid, NULL, fill_queue, tinfo)) == 0);
		  pthread_detach(threadid);

		  /* Send the sprop-parameters before any other frames */
		  send_video_frame(sendbuf, create_sprop_frame(sps, spslen, 0),
				   streamclient.videofds[0], rtpseqno_video++);
		  send_video_frame(sendbuf, create_sprop_frame(pps, ppslen, 0),
				   streamclient.videofds[0], rtpseqno_video++);

		  g_free(sps);
		  g_free(pps);

		  /* Dummy timeouts to start queue/timeout mechanism */
		  push_timeout(&queue, 100, CHECKMEDIASTATE);
		  push_timeout(&queue, 2000, CHECKMEDIASTATE);
		}
              }
              
              break;

            default:
              break;
          }
        }
      }

      if (nready <= 0) break;   
    }

    /* Set the timeout value again, since select will mess it up */
    
    lock_mutex(&queuelock);
    if (queue.size > 0) {
      CHECK((gettimeofday(&timenow, NULL)) == 0);
      *timeout = calculate_delta(&timenow, &queue.first->time);
      /* oma_debug_print("Delta sec: %ld, Delta usec: %ld\n", timeout->tv_sec, timeout->tv_usec); */

      if (timeout->tv_sec < 0) {
        timeout->tv_sec = 0;
        timeout->tv_usec = 0;
      }

      timeind = timeout;
    }
    else timeind = NULL;
    unlock_mutex(&queuelock);

  }


  return 1;
}
コード例 #20
0
ファイル: tunnel_test.c プロジェクト: Akilklk/vlc
static int server_socket(unsigned *port)
{
    int fd = socket(PF_INET6, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_TCP);
    if (fd == -1)
        return -1;

    struct sockaddr_in6 addr = {
        .sin6_family = AF_INET6,
#ifdef HAVE_SA_LEN
        .sin6_len = sizeof (addr),
#endif
        .sin6_addr = in6addr_loopback,
    };
    socklen_t addrlen = sizeof (addr);

    if (bind(fd, (struct sockaddr *)&addr, addrlen)
     || getsockname(fd, (struct sockaddr *)&addr, &addrlen))
    {
        close(fd);
        return -1;
    }

    *port = ntohs(addr.sin6_port);
    return fd;
}

int main(void)
{
    char *url;
    unsigned port;
    bool two = false;

    /* Test bad URLs */
    vlc_https_connect_proxy(NULL, "www.example.com", 0, &two,
                            "/test");
    vlc_https_connect_proxy(NULL, "www.example.com", 0, &two,
                            "ftp://proxy.example.com/");

    int lfd = server_socket(&port);
    if (lfd == -1)
        return 77;

    if (asprintf(&url, "http://[::1]:%u", port) < 0)
        url = NULL;

    assert(url != NULL);

    /* Test connection failure */
    vlc_https_connect_proxy(NULL, "www.example.com", 0, &two, url);

    if (listen(lfd, 255))
    {
        close(lfd);
        return 77;
    }

    vlc_thread_t th;
    if (vlc_clone(&th, proxy_thread, (void*)(intptr_t)lfd,
                  VLC_THREAD_PRIORITY_LOW))
        assert(!"Thread error");

    /* Test proxy error */
    vlc_https_connect_proxy(NULL, "www.example.com", 0, &two, url);

    vlc_cancel(th);
    vlc_join(th, NULL);
    assert(connection_count > 0);
    free(url);
    close(lfd);
}
コード例 #21
0
ファイル: htc.c プロジェクト: 340211173/httptunnel
int
main (int argc, char **argv)
{
  int s = -1;
  int fd = -1;
  Arguments arg;
  Tunnel *tunnel;
  int closed;

  parse_arguments (argc, argv, &arg);

  if ((debug_level == 0 || debug_file != NULL) && arg.use_daemon)
    daemon (0, 1);

#ifdef DEBUG_MODE
  if (debug_level != 0 && debug_file == NULL)
    debug_file = stderr;
#else
  openlog ("htc", LOG_PID, LOG_DAEMON);
#endif

  log_notice ("htc (%s) %s started with arguments:", PACKAGE, VERSION);
  log_notice ("  me = %s", arg.me);
  log_notice ("  device = %s", arg.device ? arg.device : "(null)");
  log_notice ("  host_name = %s", arg.host_name ? arg.host_name : "(null)");
  log_notice ("  host_port = %d", arg.host_port);
  log_notice ("  proxy_name = %s", arg.proxy_name ? arg.proxy_name : "(null)");
  log_notice ("  proxy_port = %d", arg.proxy_port);
  log_notice ("  proxy_buffer_size = %d", arg.proxy_buffer_size);
  log_notice ("  proxy_buffer_timeout = %d", arg.proxy_buffer_timeout);
  log_notice ("  content_length = %d", arg.content_length);
  log_notice ("  forward_port = %d", arg.forward_port);
  log_notice ("  max_connection_age = %d", arg.max_connection_age);
  log_notice ("  use_std = %d", arg.use_std);
  log_notice ("  strict_content_length = %d", arg.strict_content_length);
  log_notice ("  keep_alive = %d", arg.keep_alive);
  log_notice ("  proxy_authorization = %s",
	      arg.proxy_authorization ? arg.proxy_authorization : "(null)");
  log_notice ("  user_agent = %s", arg.user_agent ? arg.user_agent : "(null)");
  log_notice ("  debug_level = %d", debug_level);


  if (arg.forward_port != -1)
    {
      struct in_addr addr;

      addr.s_addr = INADDR_ANY;
      s = server_socket (addr, arg.forward_port, 0);
      log_debug ("server_socket (%d) = %d", arg.forward_port, s);
      if (s == -1)
	{
	  log_error ("couldn't create server socket: %s", strerror (errno));
	  log_exit (1);
	}
    }

#ifdef DEBUG_MODE
  signal (SIGPIPE, log_sigpipe);
#else
  signal (SIGPIPE, SIG_IGN);
#endif

  for (;;)
    {
      time_t last_tunnel_write;

      if (arg.device)
	{
	  fd = open_device (arg.device);
	  log_debug ("open_device (\"%s\") = %d", arg.device, fd);
	  if (fd == -1)
	    {
	      log_error ("couldn't open %s: %s",
			 arg.device, strerror (errno));
	      log_exit (1);
	    }
	  /* Check that fd is not 0 (clash with --stdin-stdout) */
	  if (fd == 0)
	    {
	      log_notice("changing fd from %d to 3",fd);
	      if (dup2 (fd, 3) != 3)
	        {
		  log_error ("couldn't dup2 (%d, 3): %s",fd,strerror(errno));
		  log_exit (1);
		}
	    }
	}
      else if (arg.forward_port != -1)
	{
	  log_debug ("waiting for connection on port %d", arg.forward_port);
	  fd = wait_for_connection_on_socket (s);
	  log_debug ("wait_for_connection_on_socket (%d) = %d", s, fd);
	  if (fd == -1)
	    {
	      log_error ("couldn't forward port %d: %s",
			 arg.forward_port, strerror (errno));
	      log_exit (1);
	    }
	  /* Check that fd is not 0 (clash with --stdin-stdout) */
	  if (fd == 0)
	    {
	      log_notice ("changing fd from %d to 3",fd);
	      if (dup2 (fd, 3) != 3)
	        {
		  log_error ("couldn't dup2 (%d, 3): %s",fd,strerror(errno));
		  log_exit (1);
		}
	    }
	} else if (arg.use_std) {
	  log_debug ("using stdin as fd");
	  fd = 0;
	  if (fcntl(fd,F_SETFL,O_NONBLOCK)==-1)
	    {
	      log_error ("couldn't set stdin to non-blocking mode: %s",
			 strerror(errno));
	      log_exit (1);
	    }
	  /* Usage of stdout (fd = 1) is checked later. */
	}

      log_debug ("creating a new tunnel");
      tunnel = tunnel_new_client (arg.host_name, arg.host_port,
				  arg.proxy_name, arg.proxy_port,
				  arg.content_length);
      if (tunnel == NULL)
	{
	  log_error ("couldn't create tunnel");
	  log_exit (1);
	}

      if (tunnel_setopt (tunnel, "strict_content_length",
			 &arg.strict_content_length) == -1)
	log_debug ("tunnel_setopt strict_content_length error: %s",
		   strerror (errno));

      if (tunnel_setopt (tunnel, "keep_alive",
			 &arg.keep_alive) == -1)
	log_debug ("tunnel_setopt keep_alive error: %s", strerror (errno));

      if (tunnel_setopt (tunnel, "max_connection_age",
			 &arg.max_connection_age) == -1)
	log_debug ("tunnel_setopt max_connection_age error: %s",
		   strerror (errno));

      if (arg.proxy_authorization != NULL)
	{
	  ssize_t len;
	  char *auth;

	  len = encode_base64 (arg.proxy_authorization,
			       strlen (arg.proxy_authorization),
			       &auth);
	  if (len == -1)
	    {
	      log_error ("encode_base64 error: %s", strerror (errno));
	    }
	  else
	    {
	      char *str = malloc (len + 7);

	      if (str == NULL)
		{
		  log_error ("out of memory when encoding "
			     "authorization string");
		  log_exit (1);
		}

	      strcpy (str, "Basic ");
	      strcat (str, auth);
	      free (auth);
	
	      if (tunnel_setopt (tunnel, "proxy_authorization", str) == -1)
		log_error ("tunnel_setopt proxy_authorization error: %s",
			   strerror (errno));

	      free (str);
	    }
	}

      if (arg.user_agent != NULL)
	{
	  if (tunnel_setopt (tunnel, "user_agent", arg.user_agent) == -1)
	    log_error ("tunnel_setopt user_agent error: %s",
		       strerror (errno));
	}

      if (tunnel_connect (tunnel) == -1)
	{
	  log_error ("couldn't open tunnel: %s", strerror (errno));
	  log_exit (1);
	}
      if (arg.proxy_name)
	log_notice ("connected to %s:%d via %s:%d",
		    arg.host_name, arg.host_port,
		    arg.proxy_name, arg.proxy_port);
      else
	log_notice ("connected to %s:%d", arg.host_name, arg.host_port);

      closed = FALSE;
      time (&last_tunnel_write);
      while (!closed)
	{
	  struct pollfd pollfd[2];
	  int keep_alive_timeout;
	  int timeout;
	  time_t t;
	  int n;

	  pollfd[0].fd = fd;
	  pollfd[0].events = POLLIN;
	  pollfd[1].fd = tunnel_pollin_fd (tunnel);
	  pollfd[1].events = POLLIN;
      
	  time (&t);
	  timeout = 1000 * (arg.keep_alive - (t - last_tunnel_write));
	  keep_alive_timeout = TRUE;
	  if (timeout < 0)
	    timeout = 0;
	  if (arg.proxy_buffer_timeout != -1 &&
	      arg.proxy_buffer_timeout < timeout)
	    {
	      timeout = arg.proxy_buffer_timeout;
	      keep_alive_timeout = FALSE;
	    }

	  log_annoying ("poll () ...");
	  n = poll (pollfd, 2, timeout);
	  log_annoying ("... = %d", n);
	  if (n == -1)
	    {
	      log_error ("poll error: %s", strerror (errno));
	      log_exit (1);
	    }
	  else if (n == 0)
	    {
	      log_verbose ("poll() timed out");
	      if (keep_alive_timeout)
		{
		  tunnel_padding (tunnel, 1);
		  time (&last_tunnel_write);
		}
	      else
		{
		  if (tunnel_maybe_pad (tunnel, arg.proxy_buffer_size) > 0)
		    time (&last_tunnel_write);
		}
	      continue;
	    }
      
	  handle_input ("device or port", tunnel, fd, pollfd[0].revents,
			handle_device_input, &closed);
	  handle_input ("tunnel", tunnel, fd, pollfd[1].revents,
			handle_tunnel_input, &closed);

	  if (pollfd[0].revents & POLLIN)
	    time (&last_tunnel_write);
	}

      log_debug ("destroying tunnel");
      if (fd != 0)
        {
          close (fd);
	}
      tunnel_destroy (tunnel);
      if (arg.proxy_name)
	log_notice ("disconnected from %s:%d via %s:%d",
		    arg.host_name, arg.host_port,
		    arg.proxy_name, arg.proxy_port);
      else
	log_notice ("disconnected from %s%d", arg.host_name, arg.host_port);
    }

  log_debug ("closing server socket");
  close (s);

  log_exit (0);
}
コード例 #22
0
int main (int argc, char **argv) {
    int c;
    int l_socket;
    conn *l_conn;
    struct in_addr addr;
    int lock_memory = 0;
    int daemonize = 0;

    /* initialize stuff */
    event_init();
    stats_init();
    assoc_init();
    settings_init();
    conn_init();

    /* process arguments */
    while ((c = getopt(argc, argv, "p:s:m:c:khdl:")) != -1) {
        switch (c) {
        case 'p':
            settings.port = atoi(optarg);
            break;
        case 's':
            settings.maxitems = atoi(optarg);
            break;
        case 'm':
            settings.maxbytes = atoi(optarg)*1024*1024;
            break;
        case 'c':
            settings.maxconns = atoi(optarg);
            break;
        case 'h':
            usage();
            exit(0);
        case 'k':
            lock_memory = 1;
            break;
        case 'l':
            if (!inet_aton(optarg, &addr)) {
                fprintf(stderr, "Illegal address: %s\n", optarg);
                return 1;
            } else {
                settings.interface = addr;
            }
            break;
        case 'd':
            daemonize = 1;
            break;
        default:
            fprintf(stderr, "Illegal argument \"%c\"\n", c);
            return 1;
        }
    }

    if (daemonize) {
        int child;
        child = fork();
        if (child == -1) {
            fprintf(stderr, "failed to fork() in order to daemonize\n");
            return 1;
        }
        if (child) {        /* parent */
            exit(0);
        } else {            /* child */
            setsid();       /* become a session group leader */
            child = fork(); /* stop being a session group leader */
            if (child) {    /* parent */
                exit(0);
            } else {
                int null;
                chdir("/");
                null = open("/dev/null", O_RDWR);
                dup2(null, 0);
                dup2(null, 1);
                dup2(null, 2);
                close(null);
            }
        }
    }

    /* lock paged memory if needed */
    if (lock_memory) {
        mlockall(MCL_CURRENT | MCL_FUTURE);
    }

    /* create the listening socket and bind it */
    l_socket = server_socket(settings.port);
    if (l_socket == -1) {
        fprintf(stderr, "failed to listen\n");
        exit(1);
    }

    /* create the initial listening connection */
    if (!(l_conn = conn_new(l_socket, conn_listening, EV_READ | EV_PERSIST))) {
        fprintf(stderr, "failed to create listening connection");
        exit(1);
    }

    /* initialise deletion array and timer event */
    deltotal = 200; delcurr = 0;
    todelete = malloc(sizeof(item *)*deltotal);
    delete_handler(0,0,0); /* sets up the event */

    /* enter the loop */
    event_loop(0);

    return;
}
コード例 #23
0
ファイル: memcached.c プロジェクト: naterkane/local.to
int main (int argc, char **argv) {
    int c;
    conn *l_conn;
    struct in_addr addr;
    int lock_memory = 0;
    int daemonize = 0;
    int maxcore = 0;
    char *username = 0;
    struct passwd *pw;
    struct sigaction sa;
    struct rlimit rlim;
    char *pid_file = NULL;

    /* init settings */
    settings_init();

    /* process arguments */
    while ((c = getopt(argc, argv, "p:m:Mc:khirvdl:u:P:")) != -1) {
        switch (c) {
        case 'p':
            settings.port = atoi(optarg);
            break;
        case 'm':
            settings.maxbytes = atoi(optarg)*1024*1024;
            break;
        case 'M':
            settings.evict_to_free = 0;
            break;
        case 'c':
            settings.maxconns = atoi(optarg);
            break;
        case 'h':
            usage();
            exit(0);
        case 'i':
            usage_license();
            exit(0);
        case 'k':
            lock_memory = 1;
            break;
        case 'v':
            settings.verbose++;
            break;
        case 'l':
            if (!inet_aton(optarg, &addr)) {
                fprintf(stderr, "Illegal address: %s\n", optarg);
                return 1;
            } else {
                settings.interface = addr;
            }
            break;
        case 'd':
            daemonize = 1;
            break;
        case 'r':
            maxcore = 1;
            break;
        case 'u':
            username = optarg;
            break;
        case 'P':
            pid_file = optarg;
            break;
        default:
            fprintf(stderr, "Illegal argument \"%c\"\n", c);
            return 1;
        }
    }

    if (maxcore) {
        struct rlimit rlim_new;
        /*
         * First try raising to infinity; if that fails, try bringing
         * the soft limit to the hard.
         */
        if (getrlimit(RLIMIT_CORE, &rlim)==0) {
            rlim_new.rlim_cur = rlim_new.rlim_max = RLIM_INFINITY;
            if (setrlimit(RLIMIT_CORE, &rlim_new)!=0) {
                /* failed. try raising just to the old max */
                rlim_new.rlim_cur = rlim_new.rlim_max =
                                        rlim.rlim_max;
                (void) setrlimit(RLIMIT_CORE, &rlim_new);
            }
        }
        /*
         * getrlimit again to see what we ended up with. Only fail if
         * the soft limit ends up 0, because then no core files will be
         * created at all.
         */

        if ((getrlimit(RLIMIT_CORE, &rlim)!=0) || rlim.rlim_cur==0) {
            fprintf(stderr, "failed to ensure corefile creation\n");
            exit(1);
        }
    }

    /*
     * If needed, increase rlimits to allow as many connections
     * as needed.
     */

    if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
        fprintf(stderr, "failed to getrlimit number of files\n");
        exit(1);
    } else {
        int maxfiles = settings.maxconns;
        if (rlim.rlim_cur < maxfiles)
            rlim.rlim_cur = maxfiles + 3;
        if (rlim.rlim_max < rlim.rlim_cur)
            rlim.rlim_max = rlim.rlim_cur;
        if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
            fprintf(stderr, "failed to set rlimit for open files. Try running as root or requesting smaller maxconns value.\n");
            exit(1);
        }
    }

    /*
     * initialization order: first create the listening socket
     * (may need root on low ports), then drop root if needed,
     * then daemonise if needed, then init libevent (in some cases
     * descriptors created by libevent wouldn't survive forking).
     */

    /* create the listening socket and bind it */
    l_socket = server_socket(settings.port);
    if (l_socket == -1) {
        fprintf(stderr, "failed to listen\n");
        exit(1);
    }

    /* lose root privileges if we have them */
    if (getuid()== 0 || geteuid()==0) {
        if (username==0 || *username=='\0') {
            fprintf(stderr, "can't run as root without the -u switch\n");
            return 1;
        }
        if ((pw = getpwnam(username)) == 0) {
            fprintf(stderr, "can't find the user %s to switch to\n", username);
            return 1;
        }
        if (setgid(pw->pw_gid)<0 || setuid(pw->pw_uid)<0) {
            fprintf(stderr, "failed to assume identity of user %s\n", username);
            return 1;
        }
    }

    /* daemonize if requested */
    /* if we want to ensure our ability to dump core, don't chdir to / */
    if (daemonize) {
        int res;
        res = daemon(maxcore, settings.verbose);
        if (res == -1) {
            fprintf(stderr, "failed to daemon() in order to daemonize\n");
            return 1;
        }
    }


    /* initialize other stuff */
    item_init();
    event_init();
    stats_init();
    assoc_init();
    conn_init();
    slabs_init(settings.maxbytes);

    /* lock paged memory if needed */
    if (lock_memory) {
#ifdef HAVE_MLOCKALL
        mlockall(MCL_CURRENT | MCL_FUTURE);
#else
        fprintf(stderr, "warning: mlockall() not supported on this platform.  proceeding without.\n");
#endif
    }

    /*
     * ignore SIGPIPE signals; we can use errno==EPIPE if we
     * need that information
     */
    sa.sa_handler = SIG_IGN;
    sa.sa_flags = 0;
    if (sigemptyset(&sa.sa_mask) == -1 ||
            sigaction(SIGPIPE, &sa, 0) == -1) {
        perror("failed to ignore SIGPIPE; sigaction");
        exit(1);
    }

    /* create the initial listening connection */
    if (!(l_conn = conn_new(l_socket, conn_listening, EV_READ | EV_PERSIST))) {
        fprintf(stderr, "failed to create listening connection");
        exit(1);
    }

    /* initialise deletion array and timer event */
    deltotal = 200;
    delcurr = 0;
    todelete = malloc(sizeof(item *)*deltotal);
    delete_handler(0,0,0); /* sets up the event */

    /* save the PID in if we're a daemon */
    if (daemonize)
        save_pid(getpid(),pid_file);

    /* enter the loop */
    event_loop(0);

    /* remove the PID file if we're a daemon */
    if (daemonize)
        remove_pidfile(pid_file);

    return 0;
}
コード例 #24
0
void server_init (engine_t *E, server_functions_t *F, conn_type_t *listen_connection_type, void *listen_connection_extra) {
  if (F != NULL) {
    if (F->sighup) {
      sf.sighup = F->sighup;
    }
    if (F->sigusr1) {
      sf.sigusr1 = F->sigusr1;
    }
    if (F->save_index) {
      sf.save_index = F->save_index;
    }
    if (F->cron) {
      sf.cron = F->cron;
    }
  }
  
  init_epoll ();
  init_netbuffers ();
  if (udp_enabled) {
    init_msg_buffers (0);
  }
  
  if (daemonize) {
    setsid ();
    reopen_logs ();
  }

  if (!E->sfd) {
    E->sfd = server_socket (port, E->settings_addr, backlog, 0);
  }

  if (E->sfd < 0) {
    kprintf ("cannot open server socket at port %d: %m\n", port);
    exit (1);
  }

  if (change_user (username) < 0) {
    kprintf ("fatal: cannot change user to %s\n", username ? username : "******");
    exit (1);
  }

  if (binlogname && !binlog_disabled) {
    assert (append_to_binlog (Binlog) == log_readto_pos);
  }

  init_listening_connection (E->sfd, listen_connection_type, listen_connection_extra);
  if (udp_enabled) {
    add_udp_socket (port, 0);
  }
  
  if (binlog_disabled && binlog_fd >= 0) {
    epoll_pre_event = read_new_events;
  }

  struct sigaction sa;
  memset (&sa, 0, sizeof (sa));
  sa.sa_handler = sigint_handler;
  sigemptyset (&sa.sa_mask);
  sigaddset (&sa.sa_mask, SIGTERM); 
  sigaction (SIGINT, &sa, NULL);
  
  sa.sa_handler = sigterm_handler;
  sigemptyset (&sa.sa_mask);
  sigaddset (&sa.sa_mask, SIGINT);
  sigaction (SIGTERM, &sa, NULL);
  
  sa.sa_handler = SIG_IGN;
  sigaction (SIGPIPE, &sa, NULL);
  sigaction (SIGPOLL, &sa, NULL);
  
  if (daemonize) {
    sa.sa_handler = sighup_handler;
    sigemptyset (&sa.sa_mask);
    sigaction (SIGHUP, &sa, NULL);
  }
}
コード例 #25
0
ファイル: server.c プロジェクト: tsu14/HTTP2RTSP
int start_server(const char *url, const char *rtspport)
{
  int mediafd = -1, listenfd, tempfd, maxfd;
  int videofd;
  struct addrinfo *info;
  struct sockaddr_storage remoteaddr;
  socklen_t addrlen = sizeof remoteaddr;
  fd_set readfds, masterfds;
  int nready, i;
  int videosize, videoleft;
  int recvd, sent;
  char urlhost[URLSIZE], urlpath[URLSIZE], tempstr[URLSIZE];
  unsigned char msgbuf[BUFSIZE], sendbuf[BUFSIZE];
  char *temp;
  RTSPMsg rtspmsg;
  Client streamclient;


  /* The current state of the protocol */
  int mediastate = IDLE;
  int quit = 0;

  init_client(&streamclient);

  /* Open the a file where the video is to be stored */
  if ((videofd = open("videotemp.mp4", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
    fatal_error("Error opening the temporary videofile");
  }

  /* Create the RTSP listening socket */
  resolve_host(NULL, rtspport, SOCK_STREAM, AI_PASSIVE, &info);
  listenfd = server_socket(info);
  maxfd = listenfd;


  FD_ZERO(&readfds);
  FD_ZERO(&masterfds);
  FD_SET(listenfd, &masterfds);


  while (!quit) {

    readfds = masterfds;

    if ((nready = Select(maxfd + 1, &readfds, NULL)) == -1) {
      write_log(logfd, "Select interrupted by a signal\n");
    } 

    for (i = 0; i <= maxfd; i++) {
      if (FD_ISSET(i, &readfds)) {

        nready--;

        /* New connection from a client */
        if (i == listenfd) {
          if ((tempfd = accept(i, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) {
            if (errno != EWOULDBLOCK && errno != ECONNABORTED &&
                errno != EPROTO && errno != EINTR)
            {
              fatal_error("accept");
            }
          }

          /* If we are already serving a client, close the new connection. Otherwise, continue. */
          if (streamclient.state != NOCLIENT) close (tempfd);
          else {
            streamclient.rtspfd = tempfd;
            streamclient.state = CLICONNECTED;
            maxfd = max(2, streamclient.rtspfd, maxfd);
            FD_SET(streamclient.rtspfd, &masterfds);
          }
        }

        /* Data from the media source */
        else if (i == mediafd) {

          switch (mediastate) {

            case GETSENT:
              /* Read ONLY the HTTP message from the socket and store the video size */
              recvd = recv_all(i, msgbuf, BUFSIZE, MSG_PEEK);
              temp = strstr((char *)msgbuf, "\r\n\r\n");
              recvd = recv_all(i, msgbuf, (int)(temp + 4 - (char *)msgbuf), 0);
              temp = strstr((char *)msgbuf, "Content-Length:");
              sscanf(temp, "Content-Length: %d", &videosize);
              videoleft = videosize;
              mediastate = RECVTCP;
              break;

            case RECVTCP:
              if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) {
                FD_CLR(i, &masterfds);
                close(i);
                printf("Socket closed\n");
              }
              writestr(videofd, msgbuf, recvd);
              videoleft -= recvd;
              if (videoleft <= 0) mediastate = STREAM;
              break;

              /* TODO: Start streaming, currently just exits the program */
            case STREAM:
              /*
                 close(videofd);
                 close(mediafd);
                 close(listenfd);
                 quit = 1;
                 */
              break;

            default: 
              break;
          }
        }

        /* Data from a client ( i == streamclient.rtspfd) */
        else {

          if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) {
            FD_CLR(i, &masterfds);
            close(i);
            printf("Socket closed\n");
            streamclient.state = NOCLIENT;
          }
          else {
            printf("%s", msgbuf);
            parse_rtsp(&rtspmsg, msgbuf); 
          }

          switch (streamclient.state) {

            case CLICONNECTED:
              if (rtspmsg.type == OPTIONS) {
                sent = rtsp_options(&rtspmsg, sendbuf);
                send_all(i, sendbuf, sent);
              }
              else if (rtspmsg.type == DESCRIBE) {

                /* Start fetching the file from the server */
                parse_url(url, urlhost, urlpath);
                resolve_host(urlhost, "80", SOCK_STREAM, 0, &info);
                mediafd = client_socket(info, 0);
                FD_SET(mediafd, &masterfds);
                maxfd = max(2, maxfd, mediafd);

                /* Send the GET message */
                http_get(url, msgbuf);
                send_all(mediafd, msgbuf, strlen((char *)msgbuf));
                mediastate = GETSENT;

                /* TODO: parse SDP from the media file rather than hardcoding it */
                sent = rtsp_describe(&rtspmsg, sendbuf);
                send_all(i, sendbuf, sent);
                streamclient.state = SDPSENT;
              }
              break;

            case SDPSENT:
              if (rtspmsg.type == SETUP) {
                sent = rtsp_setup(&rtspmsg, sendbuf, 50508, 50509);
                send_all(i, sendbuf, sent);
                write_remote_ip(tempstr, streamclient.rtspfd);
                resolve_host(tempstr, rtspmsg.clirtpport, 0, SOCK_DGRAM, &info); 
                streamclient.videofds[0] = client_socket(info, 50508);
                resolve_host(tempstr, rtspmsg.clirtcpport, 0, SOCK_DGRAM, &info);
                streamclient.videofds[1] = client_socket(info, 50509);
                streamclient.state = SETUPSENT;
              }
              break;

            case SETUPSENT:
              if (rtspmsg.type == PLAY) {
              }
              
              break;

            default:
              break;
          }
        }
      }
      if (nready <= 0) break;   
    }

  }


  return 1;
}