Beispiel #1
0
static BOOL
log_connection (conn_t * conn, int event, config_t * conf)
{
	switch (event) {
	case LOG_EVT_SERVERSTART:
		if (locksinit == FALSE)
			os_mutex_init (&connection_filelock);
		if (config_getConnLog (conf)) {
			os_mutex_lock (&connection_filelock);
			logfile = fopen (config_getConnLog (conf), "a");
			os_mutex_unlock (&connection_filelock);
		} else {
			logfile = NULL;
		}
		break;
	case LOG_EVT_SERVERCLOSE:
		if (logfile) {
			os_mutex_lock (&connection_filelock);
			fclose (logfile);
			logfile = NULL;
			os_mutex_unlock (&connection_filelock);
		}
		break;
	case LOG_EVT_SERVERRESTART:
		log_connection (conn, LOG_EVT_SERVERCLOSE, conf);
		log_connection (conn, LOG_EVT_SERVERSTART, conf);
		break;
	case LOG_EVT_LOG:
		if (logfile)
			return connection_real_log (conn);
		break;
	}
	return TRUE;
}
Beispiel #2
0
int		handle_client(t_selfd *fd, t_server *serv)
{
  char		*cmd;
  int		r;
  ssize_t      	swr;

  if (ISREADABLE(fd))
    {
      if (((r = read_from_client(fd)) < 0 && errno != EINTR) || (r == 0))
        {
          log_connection(((t_client *)fd->data)->sock,
                         "Client disconnected from:");
          return (destroy_connection(serv, fd));
        }
    }
  if (ISWRITEABLE(fd) && (r = write_to_client(fd)) < 0 && errno != EINTR)
    return (destroy_connection(serv, fd));
  while ((cmd = get_command(fd)))
    handle_add_cmd(serv, fd, cmd);
  swr = ring_buffer_left_read(fd->wbuff);
  if (!swr && fd->to_close)
    return (destroy_connection(serv, fd));
  if (swr)
    CHECKWRITE(fd);
  CHECKREAD(fd);
  push_instruction(serv, fd);
  return (0);
}
Beispiel #3
0
int			handle_newconnection(t_selfd *fd, t_server *serv)
{
  t_net			*bind_sock;
  t_net			*nsock;
  t_selfd		*tmpfd;
  t_client		*client;

  CHECKREAD(fd);
  if (!ISREADABLE(fd))
    return (EXIT_FAILURE);
  bind_sock = (t_net*)fd->data;
  if (!(nsock = accept_connection(bind_sock)))
    return (EXIT_FAILURE);
  if ((!(client = malloc(sizeof(t_client))))
      || !(tmpfd = create_fd(nsock->socket, client, &handle_client)))
    {
      free(client);
      close_connection(nsock);
      return (EXIT_FAILURE);
    }
  nsock->peer = peer(nsock);
  client->sock = nsock;
  log_connection(nsock, "New connection from:");
  return (init_new_client(serv, tmpfd, client));
}
Beispiel #4
0
static bool get_info(netplay_t *netplay)
{
   unsigned sram_size;
   uint32_t header[3];
   const void *sram = NULL;
   global_t *global = global_get_ptr();

   if (!socket_receive_all_blocking(netplay->fd, header, sizeof(header)))
   {
      RARCH_ERR("Failed to receive header from client.\n");
      return false;
   }

   if (global->content_crc != ntohl(header[0]))
   {
      RARCH_ERR("Content CRC32s differ. Cannot use different games.\n");
      return false;
   }

   if (implementation_magic_value() != ntohl(header[1]))
   {
      RARCH_ERR("Implementations differ, make sure you're using exact same libretro implementations and RetroArch version.\n");
      return false;
   }

   if (core.retro_get_memory_size(RETRO_MEMORY_SAVE_RAM) != ntohl(header[2]))
   {
      RARCH_ERR("Content SRAM sizes do not correspond.\n");
      return false;
   }

   if (!get_nickname(netplay, netplay->fd))
   {
      RARCH_ERR("Failed to get nickname from client.\n");
      return false;
   }

   /* Send SRAM data to our User 2. */
   sram      = core.retro_get_memory_data(RETRO_MEMORY_SAVE_RAM);
   sram_size = core.retro_get_memory_size(RETRO_MEMORY_SAVE_RAM);

   if (!socket_send_all_blocking(netplay->fd, sram, sram_size))
   {
      RARCH_ERR("Failed to send SRAM data to client.\n");
      return false;
   }

   if (!send_nickname(netplay, netplay->fd))
   {
      RARCH_ERR("Failed to send nickname to client.\n");
      return false;
   }

#ifndef HAVE_SOCKET_LEGACY
   log_connection(&netplay->other_addr, 0, netplay->other_nick);
#endif

   return true;
}
Beispiel #5
0
/* Child process that finds out what to connect to and proxies 
 */
void start_shoveler(int in_socket)
{
   fd_set fds;
   struct timeval tv;
   int res = PROBE_AGAIN;
   int out_socket;
   struct connection cnx;

   init_cnx(&cnx);
   cnx.q[0].fd = in_socket;

   FD_ZERO(&fds);
   FD_SET(in_socket, &fds);
   memset(&tv, 0, sizeof(tv));
   tv.tv_sec = probing_timeout;

   while (res == PROBE_AGAIN) {
       /* POSIX does not guarantee that tv will be updated, but the client can
        * only postpone the inevitable for so long */
       res = select(in_socket + 1, &fds, NULL, NULL, &tv);
       if (res == -1)
           perror("select");

       if (FD_ISSET(in_socket, &fds)) {
           /* Received data: figure out what protocol it is */
           res = probe_client_protocol(&cnx);
       } else {
           /* Timed out: it's necessarily SSH */
           cnx.proto = timeout_protocol();
           break;
       }
   }

   if (cnx.proto->service &&
       check_access_rights(in_socket, cnx.proto->service)) {
       exit(0);
   }

   /* Connect the target socket */
   out_socket = connect_addr(&cnx, in_socket);
   CHECK_RES_DIE(out_socket, "connect");

   cnx.q[1].fd = out_socket;

   log_connection(&cnx);

   flush_deferred(&cnx.q[1]);

   shovel(&cnx);

   close(in_socket);
   close(out_socket);
   
   if (verbose)
      fprintf(stderr, "connection closed down\n");

   exit(0);
}
Beispiel #6
0
static bool get_info(netplay_t *handle)
{
   uint32_t header[3];

   if (!recv_all(handle->fd, header, sizeof(header)))
   {
      RARCH_ERR("Failed to receive header from client.\n");
      return false;
   }

   if (g_extern.cart_crc != ntohl(header[0]))
   {
      RARCH_ERR("Cart CRC32s differ. Cannot use different games.\n");
      return false;
   }

   if (implementation_magic_value() != ntohl(header[1]))
   {
      RARCH_ERR("Implementations differ, make sure you're using exact same libretro implementations and RetroArch version.\n");
      return false;
   }

   if (pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM) != ntohl(header[2]))
   {
      RARCH_ERR("Cartridge SRAM sizes do not correspond.\n");
      return false;
   }

   if (!get_nickname(handle, handle->fd))
   {
      RARCH_ERR("Failed to get nickname from client.\n");
      return false;
   }

   // Send SRAM data to our Player 2.
   const void *sram = pretro_get_memory_data(RETRO_MEMORY_SAVE_RAM);
   unsigned sram_size = pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM);
   if (!send_all(handle->fd, sram, sram_size))
   {
      RARCH_ERR("Failed to send SRAM data to client.\n");
      return false;
   }

   if (!send_nickname(handle, handle->fd))
   {
      RARCH_ERR("Failed to send nickname to client.\n");
      return false;
   }

#ifndef HAVE_SOCKET_LEGACY
   log_connection(&handle->other_addr, 0, handle->other_nick);
#endif

   return true;
}
Beispiel #7
0
BOOL
log_log (conn_t * conn, int event, int subtype, config_t * conf)
{
	switch (event) {
	case LOG_EVT_LOG:
		switch (subtype) {
		case LOG_TYPE_CONNECTIONESTABLISHED:
			return log_connection (conn, event, conn->conf);
			break;
		case LOG_TYPE_CONNECTIONCLOSE:
			return log_summary (conn, event, conn->conf);
			break;
		}
		break;
	default:
		log_connection (conn, event, conf);
		log_summary (conn, event, conf);
		break;
	}
	return TRUE;
}
Beispiel #8
0
void log_connection_all()
{
    int i;
    connection *cxt;
    if(! (config.cflags & CONFIG_CXWRITE))
        return;
    for(i = 0; i < BUCKET_SIZE; i++) {
        cxt = bucket[i];
        while(cxt) {
            log_connection(cxt, stdout, CX_HUMAN);
            cxt = cxt->next;
        }
    }
}
Beispiel #9
0
void end_all_sessions()
{
    connection *cxt;
    int cxkey;

    for (cxkey = 0; cxkey < BUCKET_SIZE; cxkey++) {
        cxt = bucket[cxkey];
        while (cxt != NULL) {
            connection *tmp = cxt;

            if(config.cflags & CONFIG_CXWRITE)
                log_connection(cxt, stdout, CX_ENDED);

            cxt = cxt->next;
            del_connection(tmp, &bucket[cxkey]);
            if (cxt == NULL) {
                bucket[cxkey] = NULL;
            }
        }
    }
}
Beispiel #10
0
static void netplay_pre_frame_spectate(netplay_t *handle)
{
   unsigned i;
   if (handle->spectate_client)
      return;

   fd_set fds;
   FD_ZERO(&fds);
   FD_SET(handle->fd, &fds);

   struct timeval tmp_tv = {0};
   if (select(handle->fd + 1, &fds, NULL, NULL, &tmp_tv) <= 0)
      return;

   if (!FD_ISSET(handle->fd, &fds))
      return;

   struct sockaddr_storage their_addr;
   socklen_t addr_size = sizeof(their_addr);
   int new_fd = accept(handle->fd, (struct sockaddr*)&their_addr, &addr_size);
   if (new_fd < 0)
   {
      RARCH_ERR("Failed to accept incoming spectator.\n");
      return;
   }

   int index = -1;
   for (i = 0; i < MAX_SPECTATORS; i++)
   {
      if (handle->spectate_fds[i] == -1)
      {
         index = i;
         break;
      }
   }

   // No vacant client streams :(
   if (index == -1)
   {
      close(new_fd);
      return;
   }

   if (!get_nickname(handle, new_fd))
   {
      RARCH_ERR("Failed to get nickname from client.\n");
      close(new_fd);
      return;
   }

   if (!send_nickname(handle, new_fd))
   {
      RARCH_ERR("Failed to send nickname to client.\n");
      close(new_fd);
      return;
   }

   size_t header_size;
   uint32_t *header = bsv_header_generate(&header_size, implementation_magic_value());
   if (!header)
   {
      RARCH_ERR("Failed to generate BSV header.\n");
      close(new_fd);
      return;
   }

   int bufsize = header_size;
   setsockopt(new_fd, SOL_SOCKET, SO_SNDBUF, CONST_CAST &bufsize, sizeof(int));

   if (!send_all(new_fd, header, header_size))
   {
      RARCH_ERR("Failed to send header to client.\n");
      close(new_fd);
      free(header);
      return;
   }

   free(header);
   handle->spectate_fds[index] = new_fd;

#ifndef HAVE_SOCKET_LEGACY
   log_connection(&their_addr, index, handle->other_nick);
#endif
}
Beispiel #11
0
static int http_server(void)
{
    int server_fd = 0;
	int ctrl_fd = 0, ctrl_fd2 = 0;
    int ret, delay;
    struct pollfd *poll_table, *poll_entry;
    HTTPContext *c, *c_next;
    if(!(poll_table = av_mallocz_array(nb_max_http_connections + 1, sizeof(*poll_table)))) {
        http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections);
        return -1;
    }

	#if defined(PLUGIN_DVB)
	ctrl_fd = ff_ctl_open(1234);
    if (ctrl_fd < 0) {
        av_free(poll_table);
        return -1;
    }
	#endif
	
    if (my_http_addr.sin_port) {
        server_fd = socket_open_listen(&my_http_addr);
        if (server_fd < 0) {
            av_free(poll_table);
            return -1;
        }
    }

    if ( !server_fd) {
        http_log("HTTP disabled.\n");
        av_free(poll_table);
        return -1;
    }
	
	#if defined(PLUGIN_SSDP)
	ssdp_fd = mcast_open(ssdp_ip, ssdp_port);
	if(ssdp_fd <= 0){
		http_log("ssdp disabled\n");
	}
	ssdp_notify(ssdp_fd, ssdp_ip, ssdp_port, "ssdp:alive");
	#endif
	
    http_log("FFserver started.\n");

    for(;;) {
        poll_entry = poll_table;
		
		#if defined(PLUGIN_DVB)
		if(ctrl_fd){
			poll_entry->fd = ctrl_fd;
            poll_entry->events = POLLIN;
            poll_entry++;
		}
		if(ctrl_fd2){
			poll_entry->fd = ctrl_fd2;
			poll_entry->events = POLLIN;
			if(ctl_msg_pending() > 0){
				poll_entry->events |= POLLOUT;
			}
            poll_entry++;
		}
		#endif
		
        if (server_fd) {
            poll_entry->fd = server_fd;
            poll_entry->events = POLLIN;
            poll_entry++;
        }
		
		#if defined(PLUGIN_SSDP)
		if(ssdp_fd){
			poll_entry->fd = ssdp_fd;
            poll_entry->events = POLLIN;
            poll_entry++;
		}
		#endif

        /* wait for events on each HTTP handle */
        c = first_http_ctx;
        delay = 1500;
        while (c != NULL) {
            int fd;
            fd = c->fd;
            switch(c->state) {
            case HTTPSTATE_SEND_HEADER:
                c->poll_entry = poll_entry;
                poll_entry->fd = fd;
                poll_entry->events = POLLOUT;
                poll_entry++;
                break;
            case HTTPSTATE_SEND_DATA_HEADER:
            case HTTPSTATE_SEND_DATA:
            case HTTPSTATE_SEND_DATA_TRAILER:
                /*for TCP, we output as much as we can*/
                c->poll_entry = poll_entry;
                poll_entry->fd = fd;
                poll_entry->events = POLLOUT;
                poll_entry++;
                break;
            case HTTPSTATE_WAIT_REQUEST:
            case HTTPSTATE_RECEIVE_DATA:
            case HTTPSTATE_WAIT_FEED:
                /* need to catch errors */
                c->poll_entry = poll_entry;
                poll_entry->fd = fd;
                poll_entry->events = POLLIN;/* Maybe this will work */
                poll_entry++;
                break;
            default:
                c->poll_entry = NULL;
                break;
            }
            c = c->next;
        }

        /* wait for an event on one connection. We poll at least every second to handle timeouts */
        do {
            ret = poll(poll_table, poll_entry - poll_table, delay);
            if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) &&
                ff_neterrno() != AVERROR(EINTR)) {
                av_free(poll_table);
                return -1;
            }
        } while (ret < 0);

        cur_time = av_gettime() / 1000;

        /* now handle the events */
        for(c = first_http_ctx; c != NULL; c = c_next) {
            c_next = c->next;
            if (handle_connection(c) < 0) {
                log_connection(c);
                close_connection(c);
            }
        }

        poll_entry = poll_table;

		#if defined(PLUGIN_DVB)
		if(ctrl_fd){
			if(poll_entry->revents & POLLIN){
				ctrl_fd2 = ctl_msg_open(ctrl_fd);
			}
			poll_entry++;
		}
		if(ctrl_fd2 && poll_entry->fd == ctrl_fd2){
			if(poll_entry->revents & POLLIN){
				ctl_msg_recv();
				ff_ctl_recv(ctl_msg_cb);
			}else if(poll_entry->revents & POLLOUT){
				ctl_msg_send();
			}
			poll_entry++;
		}
		#endif
		if(poll_entry->fd != server_fd){
			printf("bad  entry\n");
		}
		
        if (server_fd) {
            if (poll_entry->revents & POLLIN)
                new_connection(server_fd, 0);
            poll_entry++;
        }
		
		#if defined(PLUGIN_SSDP)
		if (ssdp_fd) {
            if (poll_entry->revents & POLLIN)
                ssdp_response(ssdp_fd);
            poll_entry++;
        }
		#endif
	
    }
}
Beispiel #12
0
void end_sessions()
{

    connection *cxt;
    time_t check_time;
    check_time = time(NULL);
    int ended, expired = 0;
    uint32_t curcxt = 0;
    
    int iter;
    for (iter = 0; iter < BUCKET_SIZE; iter++) {
        cxt = bucket[iter];
        while (cxt != NULL) {
            ended = 0;
            curcxt++;
            /* TCP */
            if (cxt->proto == IP_PROTO_TCP) {
                /* * FIN from both sides */
                if (cxt->s_tcpFlags & TF_FIN && cxt->d_tcpFlags & TF_FIN
                    && (check_time - cxt->last_pkt_time) > 5) {
                    ended = 1;
                } /* * RST from either side */
                else if ((cxt->s_tcpFlags & TF_RST
                          || cxt->d_tcpFlags & TF_RST)
                          && (check_time - cxt->last_pkt_time) > 5) {
                    ended = 1;
                }
                else if ((check_time - cxt->last_pkt_time) > TCP_TIMEOUT) {
                    expired = 1;
                }
            }
            /* UDP */
            else if (cxt->proto == IP_PROTO_UDP
                     && (check_time - cxt->last_pkt_time) > 60) {
                expired = 1;
            }
            /* ICMP */
            else if (cxt->proto == IP_PROTO_ICMP
                     || cxt->proto == IP6_PROTO_ICMP) {
                if ((check_time - cxt->last_pkt_time) > 60) {
                     expired = 1;
                }
            }
            /* All Other protocols */
            else if ((check_time - cxt->last_pkt_time) > TCP_TIMEOUT) {
                expired = 1;
            }

            if (ended == 1 || expired == 1) {
                /* remove from the hash */
                if (cxt->prev)
                    cxt->prev->next = cxt->next;
                if (cxt->next)
                    cxt->next->prev = cxt->prev;
                connection *tmp = cxt;

                if (config.cflags & CONFIG_CXWRITE) {
                    if (expired == 1)
                        log_connection(cxt, stdout, CX_EXPIRE);
                    else if (ended == 1)
                        log_connection(cxt, stdout, CX_ENDED);
                }
                ended = expired = 0;

                cxt = cxt->prev;

                //CLEAR_CXT(tmp);
                del_connection(tmp, &bucket[iter]);
                if (cxt == NULL) {
                    bucket[iter] = NULL;
                }
            } else {
                cxt = cxt->prev;
            }
        }
    }
}
Beispiel #13
0
int cx_track(packetinfo *pi) {
    struct in6_addr *ip_src;
    struct in6_addr *ip_dst;
    struct in6_addr ips;
    struct in6_addr ipd;
    uint16_t src_port = pi->s_port;
    uint16_t dst_port = pi->d_port;
    int af = pi->af;
    connection *cxt = NULL;
    connection *head = NULL;
    uint32_t hash;


    if(af== AF_INET6){
        ip_src = &PI_IP6SRC(pi);
        ip_dst = &PI_IP6DST(pi);
    }else {
        // ugly hack :(
        // the way we do ip4/6 is DIRTY
        // FIX IT?!!?
        ips.s6_addr32[0] = pi->ip4->ip_src;
        ipd.s6_addr32[0] = pi->ip4->ip_dst;
        ip_src = &ips;
        ip_dst = &ipd;
    }

    // find the right connection bucket
    if (af == AF_INET) {
        hash = CXT_HASH4(IP4ADDR(ip_src),IP4ADDR(ip_dst));
    } else if (af == AF_INET6) {
        hash = CXT_HASH6(ip_src,ip_dst);
    }
    cxt = bucket[hash];
    head = cxt;

    // search through the bucket
    while (cxt != NULL) {
        // Two-way compare of given connection against connection table
        if (af == AF_INET) {
            if (CMP_CXT4(cxt,IP4ADDR(ip_src),src_port,IP4ADDR(ip_dst),dst_port)){
                // Client sends first packet (TCP/SYN - UDP?) hence this is a client
                return cxt_update_client(cxt, pi);
            } else if (CMP_CXT4(cxt,IP4ADDR(ip_dst),dst_port,IP4ADDR(ip_src),src_port)) {
                // This is a server (Maybe not when we start up but in the long run)
                return cxt_update_server(cxt, pi);
            }
        } else if (af == AF_INET6) {
            if (CMP_CXT6(cxt,ip_src,src_port,ip_dst,dst_port)){
                return cxt_update_client(cxt, pi);
            } else if (CMP_CXT6(cxt,ip_dst,dst_port,ip_src,src_port)){
                return cxt_update_server(cxt, pi);
            }
        }
        cxt = cxt->next;
    }
    // bucket turned upside down didn't yeild anything. new connection
    cxt = cxt_new(pi);
    if(config.cflags & CONFIG_CXWRITE)
        log_connection(cxt, stdout, CX_NEW);

    /* * New connections are pushed on to the head of bucket[s_hash] */
    cxt->next = head;
    if (head != NULL) {
        // are we doubly linked?
        head->prev = cxt;
    }
    bucket[hash] = cxt;
    pi->cxt = cxt;

    /* * Return value should be 1, telling to do client service fingerprinting */
    return 1;
}