static bool init_lan_ad_server_socket(netplay_t *netplay, uint16_t port)
{
   struct addrinfo *addr = NULL;
   int fd = socket_init((void **) &addr, port, NULL, SOCKET_TYPE_DATAGRAM);

   if (fd < 0)
      goto error;

   if (!socket_bind(fd, (void*)addr))
   {
      socket_close(fd);
      goto error;
   }

   lan_ad_server_fd = fd;
   freeaddrinfo_retro(addr);

   return true;

error:
   if (addr)
      freeaddrinfo_retro(addr);
   RARCH_ERR("Failed to initialize netplay advertisement socket.\n");
   return false;
}
Example #2
0
static bool remote_init_network(rarch_remote_t *handle,
      uint16_t port, unsigned user)
{
   struct addrinfo hints = {0};
   char port_buf[16]     = {0};
   struct addrinfo *res  = NULL;
   int yes               = 1;

   port = port + user;

   if (!network_init())
      return false;

   RARCH_LOG("Bringing up remote interface on port %hu.\n",
         (unsigned short)port);

#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY)
   hints.ai_family   = AF_INET;
#else
   hints.ai_family   = AF_UNSPEC;
#endif
   hints.ai_socktype = SOCK_DGRAM;
   hints.ai_flags    = AI_PASSIVE;


   snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);
   if (getaddrinfo_retro(NULL, port_buf, &hints, &res) < 0)
      goto error;

   handle->net_fd[user] = socket(res->ai_family,
         res->ai_socktype, res->ai_protocol);
   if (handle->net_fd[user] < 0)
      goto error;

   if (!socket_nonblock(handle->net_fd[user]))
      goto error;

   setsockopt(handle->net_fd[user], SOL_SOCKET,
         SO_REUSEADDR, (const char*)&yes, sizeof(int));
   if (bind(handle->net_fd[user], res->ai_addr, res->ai_addrlen) < 0)
   {
      RARCH_ERR("Failed to bind socket.\n");
      goto error;
   }

   freeaddrinfo_retro(res);
   return true;

error:
   if (res)
      freeaddrinfo_retro(res);
   return false;
}
Example #3
0
static int net_http_new_socket(const char *domain, int port)
{
   int fd;
#ifndef _WIN32
#ifndef VITA
   struct timeval timeout;
#endif
#endif
   struct addrinfo hints, *addr = NULL;
   char portstr[16] = {0};
   
   /* Initialize the network. */
   if (!network_init())
      return -1;

   snprintf(portstr, sizeof(portstr), "%i", port);

   memset(&hints, 0, sizeof(hints));
   hints.ai_family   = AF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_flags    = 0;
   
   if (getaddrinfo_retro(domain, portstr, &hints, &addr) < 0)
      return -1;
   if (!addr)
      return -1;

   fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);

#ifndef _WIN32
#ifndef VITA
   timeout.tv_sec=4;
   timeout.tv_usec=0;
   setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof timeout);
#endif
#endif
   if (connect(fd, addr->ai_addr, addr->ai_addrlen) != 0)
   {
      freeaddrinfo_retro(addr);
      socket_close(fd);
      return -1;
   }

   freeaddrinfo_retro(addr);

   if (!socket_nonblock(fd))
   {
      socket_close(fd);
      return -1;
   }

   return fd;
}
Example #4
0
/**
 * netplay_free:
 * @netplay              : pointer to netplay object
 *
 * Frees netplay handle.
 **/
void netplay_free(netplay_t *netplay)
{
   unsigned i;

   if (netplay->fd >= 0)
      socket_close(netplay->fd);

   if (netplay->spectate.enabled)
   {
      for (i = 0; i < MAX_SPECTATORS; i++)
         if (netplay->spectate.fds[i] >= 0)
            socket_close(netplay->spectate.fds[i]);

      free(netplay->spectate.input);
   }
   else
   {
      for (i = 0; i < netplay->buffer_size; i++)
         if (netplay->buffer[i].state)
            free(netplay->buffer[i].state);

      free(netplay->buffer);
   }

   if (netplay->addr)
      freeaddrinfo_retro(netplay->addr);

   free(netplay);
}
/** Discovery control */
bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state, void *data)
{
   char port_str[6];

   if (lan_ad_client_fd < 0)
      return false;

   switch (state)
   {
      case RARCH_NETPLAY_DISCOVERY_CTL_LAN_SEND_QUERY:
      {
         struct addrinfo hints = {0}, *addr;
         int canBroadcast = 1;

         /* Get the broadcast address (IPv4 only for now) */
         snprintf(port_str, 6, "%hu", (unsigned short) RARCH_DEFAULT_PORT);
         if (getaddrinfo_retro("255.255.255.255", port_str, &hints, &addr) < 0)
            return false;

         /* Make it broadcastable */
#if defined(SOL_SOCKET) && defined(SO_BROADCAST)
         if (setsockopt(lan_ad_client_fd, SOL_SOCKET, SO_BROADCAST,
                  (const char *)&canBroadcast, sizeof(canBroadcast)) < 0)
             RARCH_WARN("Failed to set netplay discovery port to broadcast.\n");
#endif

         /* Put together the request */
         memcpy((void *) &ad_packet_buffer, "RANQ", 4);
         ad_packet_buffer.protocol_version = htonl(NETPLAY_PROTOCOL_VERSION);

         /* And send it off */
         if (sendto(lan_ad_client_fd, (const char *) &ad_packet_buffer,
            2*sizeof(uint32_t), 0, addr->ai_addr, addr->ai_addrlen) <
            (ssize_t) (2*sizeof(uint32_t)))
            RARCH_WARN("Failed to send netplay discovery response.\n");

         freeaddrinfo_retro(addr);
         break;
      }

      case RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES:
         if (!netplay_lan_ad_client())
            return false;
         *((struct netplay_host_list **) data) = &discovered_hosts;
         break;

      case RARCH_NETPLAY_DISCOVERY_CTL_LAN_CLEAR_RESPONSES:
         discovered_hosts.size = 0;
         break;

      default:
         return false;
   }

   return true;
}
Example #6
0
static bool init_udp_socket(netplay_t *netplay, const char *server,
                            uint16_t port)
{
    char port_buf[16]     = {0};
    struct addrinfo hints = {0};

    memset(&hints, 0, sizeof(hints));
#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY)
    hints.ai_family = AF_INET;
#else
    hints.ai_family = AF_UNSPEC;
#endif
    hints.ai_socktype = SOCK_DGRAM;
    if (!server)
        hints.ai_flags = AI_PASSIVE;

    snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);

    if (getaddrinfo_retro(server, port_buf, &hints, &netplay->addr) < 0)
        return false;

    if (!netplay->addr)
        return false;

    netplay->udp_fd = socket(netplay->addr->ai_family,
                             netplay->addr->ai_socktype, netplay->addr->ai_protocol);

    if (netplay->udp_fd < 0)
    {
        RARCH_ERR("Failed to initialize socket.\n");
        return false;
    }

    if (!server)
    {
        /* Not sure if we have to do this for UDP, but hey :) */
        int yes = 1;

        setsockopt(netplay->udp_fd, SOL_SOCKET, SO_REUSEADDR,
                   (const char*)&yes, sizeof(int));

        if (bind(netplay->udp_fd, netplay->addr->ai_addr,
                 netplay->addr->ai_addrlen) < 0)
        {
            RARCH_ERR("Failed to bind socket.\n");
            socket_close(netplay->udp_fd);
            netplay->udp_fd = -1;
        }

        freeaddrinfo_retro(netplay->addr);
        netplay->addr = NULL;
    }

    return true;
}
Example #7
0
static bool init_tcp_socket(netplay_t *netplay, const char *server,
                            uint16_t port, bool spectate)
{
    char port_buf[16]               = {0};
    bool ret                        = false;
    const struct addrinfo *tmp_info = NULL;
    struct addrinfo hints, *res     = NULL;

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

#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY)
    hints.ai_family = AF_INET;
#else
    hints.ai_family = AF_UNSPEC;
#endif

    hints.ai_socktype = SOCK_STREAM;
    if (!server)
        hints.ai_flags = AI_PASSIVE;

    snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);
    if (getaddrinfo_retro(server, port_buf, &hints, &res) < 0)
        return false;

    if (!res)
        return false;

    /* If "localhost" is used, it is important to check every possible
     * address for IPv4/IPv6. */
    tmp_info = res;

    while (tmp_info)
    {
        int fd;
        if ((fd = init_tcp_connection(tmp_info, server, netplay->spectate.enabled,
                                      (struct sockaddr*)&netplay->other_addr,
                                      sizeof(netplay->other_addr))) >= 0)
        {
            ret = true;
            netplay->fd = fd;
            break;
        }

        tmp_info = tmp_info->ai_next;
    }

    if (res)
        freeaddrinfo_retro(res);

    if (!ret)
        RARCH_ERR("Failed to set up netplay sockets.\n");

    return ret;
}
Example #8
0
/**
 * netplay_free
 * @netplay              : pointer to netplay object
 *
 * Frees netplay data/
 */
void netplay_free(netplay_t *netplay)
{
   size_t i;

   if (netplay->listen_fd >= 0)
      socket_close(netplay->listen_fd);

   for (i = 0; i < netplay->connections_size; i++)
   {
      struct netplay_connection *connection = &netplay->connections[i];
      if (connection->active)
      {
         socket_close(connection->fd);
         netplay_deinit_socket_buffer(&connection->send_packet_buffer);
         netplay_deinit_socket_buffer(&connection->recv_packet_buffer);
      }
   }

   if (netplay->connections && netplay->connections != &netplay->one_connection)
      free(netplay->connections);

   if (netplay->nat_traversal)
      natt_free(&netplay->nat_traversal_state);

   if (netplay->buffer)
   {
      for (i = 0; i < netplay->buffer_size; i++)
         if (netplay->buffer[i].state)
            free(netplay->buffer[i].state);

      free(netplay->buffer);
   }

   if (netplay->zbuffer)
      free(netplay->zbuffer);

   if (netplay->compress_nil.compression_stream)
   {
      netplay->compress_nil.compression_backend->stream_free(netplay->compress_nil.compression_stream);
      netplay->compress_nil.decompression_backend->stream_free(netplay->compress_nil.decompression_stream);
   }
   if (netplay->compress_zlib.compression_stream)
   {
      netplay->compress_zlib.compression_backend->stream_free(netplay->compress_zlib.compression_stream);
      netplay->compress_zlib.decompression_backend->stream_free(netplay->compress_zlib.decompression_stream);
   }

   if (netplay->addr)
      freeaddrinfo_retro(netplay->addr);

   free(netplay);
}
Example #9
0
bool udp_send_packet(const char *host,
      uint16_t port, const char *msg)
{
   char port_buf[16]           = {0};
   struct addrinfo hints       = {0};
   struct addrinfo *res        = NULL;
   const struct addrinfo *tmp  = NULL;
   int fd                      = -1;
   bool ret                    = true;

   hints.ai_socktype           = SOCK_DGRAM;

   snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);

   if (getaddrinfo_retro(host, port_buf, &hints, &res) != 0)
      return false;

   /* Send to all possible targets.
    * "localhost" might resolve to several different IPs. */
   tmp = (const struct addrinfo*)res;
   while (tmp)
   {
      ssize_t len, ret_len;

      fd = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol);
      if (fd < 0)
      {
         ret = false;
         goto end;
      }

      len     = strlen(msg);
      ret_len = sendto(fd, msg, len, 0, tmp->ai_addr, tmp->ai_addrlen);

      if (ret_len < len)
      {
         ret = false;
         goto end;
      }

      socket_close(fd);
      fd = -1;
      tmp = tmp->ai_next;
   }

end:
   freeaddrinfo_retro(res);
   if (fd >= 0)
      socket_close(fd);
   return ret;
}
Example #10
0
static bool input_remote_init_network(input_remote_t *handle,
      uint16_t port, unsigned user)
{
   int fd;
   struct addrinfo *res  = NULL;

   port = port + user;

   if (!network_init())
      return false;

   RARCH_LOG("Bringing up remote interface on port %hu.\n",
         (unsigned short)port);

   fd = socket_init((void**)&res, port, NULL, SOCKET_TYPE_DATAGRAM);

   if (fd < 0)
      goto error;

   handle->net_fd[user] = fd;

   if (!socket_nonblock(handle->net_fd[user]))
      goto error;

   if (!socket_bind(handle->net_fd[user], res))
   {
      RARCH_ERR("Failed to bind socket.\n");
      goto error;
   }

   freeaddrinfo_retro(res);
   return true;

error:
   if (res)
      freeaddrinfo_retro(res);
   return false;
}
/** Initialize Netplay discovery (client) */
bool init_netplay_discovery(void)
{
   struct addrinfo *addr = NULL;
   int fd = socket_init((void **) &addr, 0, NULL, SOCKET_TYPE_DATAGRAM);

   if (fd < 0)
      goto error;

   if (!socket_bind(fd, (void*)addr))
   {
      socket_close(fd);
      goto error;
   }

   lan_ad_client_fd = fd;
   freeaddrinfo_retro(addr);
   return true;

error:
   if (addr)
      freeaddrinfo_retro(addr);
   RARCH_ERR("Failed to initialize netplay advertisement client socket.\n");
   return false;
}
Example #12
0
static int net_http_new_socket(struct http_connection_t *conn)
{
   int ret;
   struct addrinfo *addr = NULL, *next_addr = NULL;
   int fd                = socket_init(
         (void**)&addr, conn->port, conn->domain, SOCKET_TYPE_STREAM);
#ifdef HAVE_SSL
   if (conn->sock_state.ssl)
   {
      if (!(conn->sock_state.ssl_ctx = ssl_socket_init(fd, conn->domain)))
         return -1;
   }
#endif

   next_addr = addr;
   while(fd >= 0)
   {
#ifdef HAVE_SSL
      if (conn->sock_state.ssl)
      {
         ret = ssl_socket_connect(conn->sock_state.ssl_ctx, (void*)next_addr, true, true);

         if (ret >= 0)
            break;

         ssl_socket_close(conn->sock_state.ssl_ctx);
      }
      else
#endif
      {
         ret = socket_connect(fd, (void*)next_addr, true);

         if (ret >= 0 && socket_nonblock(fd))
            break;

         socket_close(fd);
      }

      fd = socket_next((void**)&next_addr);
   }

   if (addr)
      freeaddrinfo_retro(addr);

   conn->sock_state.fd = fd;

   return fd;
}
Example #13
0
bool natt_open_port_any(struct natt_status *status,
      uint16_t port, enum socket_protocol proto)
{
#if !defined(HAVE_SOCKET_LEGACY) && !defined(WIIU)
   size_t i;
   char port_str[6];
   struct net_ifinfo list;
   struct addrinfo hints = {0}, *addr;
   bool ret              = false;

   snprintf(port_str, sizeof(port_str), "%hu", port);

   /* get our interfaces */
   if (!net_ifinfo_new(&list))
      return false;

   /* loop through them */
   for (i = 0; i < list.size; i++)
   {
      struct net_ifinfo_entry *entry = list.entries + i;

      /* ignore localhost */
      if (  string_is_equal(entry->host, "127.0.0.1") || 
            string_is_equal(entry->host, "::1"))
         continue;

      /* make a request for this host */
      if (getaddrinfo_retro(entry->host, port_str, &hints, &addr) == 0)
      {
         ret = natt_open_port(status, addr->ai_addr,
               addr->ai_addrlen, proto) || ret;
         freeaddrinfo_retro(addr);
      }
   }

   net_ifinfo_free(&list);

   return ret;

#else
   return false;
#endif
}
Example #14
0
static int net_http_new_socket(const char *domain, int port)
{
   int ret;
   struct addrinfo *addr = NULL;
   int fd = socket_init((void**)&addr, port, domain, SOCKET_TYPE_STREAM);
   if (fd < 0)
      return -1;

   ret = socket_connect(fd, (void*)addr, true);

   freeaddrinfo_retro(addr);

   if (ret < 0)
      goto error;

   if (!socket_nonblock(fd))
      goto error;

   return fd;

error:
   socket_close(fd);
   return -1;
}
Example #15
0
static bool natt_open_port(struct natt_status *status,
      struct sockaddr *addr, socklen_t addrlen, enum socket_protocol proto)
{
#ifndef HAVE_SOCKET_LEGACY
#if HAVE_MINIUPNPC
   int r;
   char host[PATH_MAX_LENGTH], ext_host[PATH_MAX_LENGTH],
        port_str[6], ext_port_str[6];
   struct addrinfo hints         = {0};
   const char *proto_str         = NULL;
   struct addrinfo *ext_addrinfo = NULL;

   /* if NAT traversal is uninitialized or unavailable, oh well */
   if (!urls.controlURL || !urls.controlURL[0])
      return false;

   /* figure out the internal info */
   if (getnameinfo(addr, addrlen, host, PATH_MAX_LENGTH,
            port_str, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0)
      return false;

   proto_str = (proto == SOCKET_PROTOCOL_UDP) ? "UDP" : "TCP";

   /* add the port mapping */
   r = UPNP_AddAnyPortMapping(urls.controlURL,
         data.first.servicetype, port_str,
         port_str, host, "retroarch",
         proto_str, NULL, "3600", ext_port_str);

   if (r != 0)
   {
      /* try the older AddPortMapping */
      memcpy(ext_port_str, port_str, 6);
      r = UPNP_AddPortMapping(urls.controlURL,
            data.first.servicetype, port_str,
            port_str, host, "retroarch",
            proto_str, NULL, "3600");
   }
   if (r != 0)
      return false;

   /* get the external IP */
   r = UPNP_GetExternalIPAddress(urls.controlURL,
         data.first.servicetype, ext_host);
   if (r != 0)
      return false;

   /* update the status */
   if (getaddrinfo_retro(ext_host,
            ext_port_str, &hints, &ext_addrinfo) != 0)
      return false;

   if (ext_addrinfo->ai_family == AF_INET &&
       ext_addrinfo->ai_addrlen >= sizeof(struct sockaddr_in))
   {
      status->have_inet4     = true;
      status->ext_inet4_addr = *((struct sockaddr_in *)
            ext_addrinfo->ai_addr);
   }
#if defined(AF_INET6) && !defined(HAVE_SOCKET_LEGACY)
   else if (ext_addrinfo->ai_family == AF_INET6 &&
            ext_addrinfo->ai_addrlen >= sizeof(struct sockaddr_in6))
   {
      status->have_inet6     = true;
      status->ext_inet6_addr = *((struct sockaddr_in6 *)
            ext_addrinfo->ai_addr);
   }
#endif
   else
   {
      freeaddrinfo_retro(ext_addrinfo);
      return false;
   }

   freeaddrinfo_retro(ext_addrinfo);
   return true;

#else
   return false;
#endif
#else
   return false;
#endif
}
Example #16
0
static bool init_tcp_socket(netplay_t *netplay, void *direct_host,
      const char *server, uint16_t port)
{
   char port_buf[16];
   bool ret                        = false;
   const struct addrinfo *tmp_info = NULL;
   struct addrinfo *res            = NULL;
   struct addrinfo hints           = {0};

   port_buf[0] = '\0';

   if (!direct_host)
   {
#ifdef HAVE_INET6
      /* Default to hosting on IPv6 and IPv4 */
      if (!server)
         hints.ai_family = AF_INET6;
#endif
      hints.ai_socktype = SOCK_STREAM;
      if (!server)
         hints.ai_flags = AI_PASSIVE;

      snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);
      if (getaddrinfo_retro(server, port_buf, &hints, &res) < 0)
      {
#ifdef HAVE_INET6
         if (!server)
         {
            /* Didn't work with IPv6, try wildcard */
            hints.ai_family = 0;
            if (getaddrinfo_retro(server, port_buf, &hints, &res) < 0)
               return false;
         }
         else
#endif
         return false;
      }

      if (!res)
         return false;

   }
   else
   {
      /* I'll build my own addrinfo! With blackjack and hookers! */
      struct netplay_host *host = (struct netplay_host *) direct_host;
      hints.ai_family = host->addr.sa_family;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = 0;
      hints.ai_addrlen = host->addrlen;
      hints.ai_addr = &host->addr;
      res = &hints;

   }

   /* If we're serving on IPv6, make sure we accept all connections, including
    * IPv4 */
#ifdef HAVE_INET6
   if (!direct_host && !server && res->ai_family == AF_INET6)
   {
      struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) res->ai_addr;
      sin6->sin6_addr = in6addr_any;
   }
#endif

   /* If "localhost" is used, it is important to check every possible 
    * address for IPv4/IPv6. */
   tmp_info = res;

   while (tmp_info)
   {
      struct sockaddr_storage sad;
      int fd = init_tcp_connection(
            tmp_info,
            direct_host || server,
            (struct sockaddr*)&sad,
            sizeof(sad));

      if (fd >= 0)
      {
         ret = true;
         if (direct_host || server)
         {
            netplay->connections[0].active = true;
            netplay->connections[0].fd = fd;
            netplay->connections[0].addr = sad;
         }
         else
         {
            netplay->listen_fd = fd;
         }
         break;
      }

      tmp_info = tmp_info->ai_next;
   }

   if (res && !direct_host)
      freeaddrinfo_retro(res);

   if (!ret)
      RARCH_ERR("Failed to set up netplay sockets.\n");

   return ret;
}