Ejemplo n.º 1
0
static s32 tcp_socket(void)
{
	s32 s, res;

	s = net_socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
	if (s < 0)
		return s;

	// Switch off Nagle with TCP_NODELAY
	u32 nodelay = 1;
	net_setsockopt(s,IPPROTO_TCP,TCP_NODELAY,&nodelay,sizeof(nodelay));

	res = net_fcntl(s, F_GETFL, 0);
	if (res < 0)
	{
		net_close(s);
		return res;
	}

	res = net_fcntl(s, F_SETFL, res | IOS_O_NONBLOCK);
	if (res < 0)
	{
		net_close(s);
		return res;
	}

	return s;
}
Ejemplo n.º 2
0
void network_init()
{
	struct sockaddr_in my_name;

	my_name.sin_family = AF_INET;
	my_name.sin_port = htons(SERVER_PORT);
	my_name.sin_addr.s_addr = htonl(INADDR_ANY);

	net_init();

	server_socket = net_socket(AF_INET, SOCK_STREAM, 0);
	int yes = 1;
	net_setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

	while(net_bind(server_socket, (struct sockaddr*)&my_name, sizeof(my_name)) < 0)
	{
	}

	net_listen(server_socket, 0);

	struct sockaddr_in client_info;
	socklen_t ssize = sizeof(client_info);
	client_socket = net_accept(server_socket, (struct sockaddr*)&client_info, &ssize);

	network_printf("Hello world!\n");
}
Ejemplo n.º 3
0
int net_set_reuseaddress(int fd, int toggle)
{
	int ret;
	ret = net_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &toggle, sizeof(toggle));
	if (ret == -1)
	{
		net_error_out(fd, "net_set_reuseaddress");
	}
	return ret;
}
Ejemplo n.º 4
0
int net_set_keepalive(int fd, int toggle)
{
	int ret;
	ret = net_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &toggle, sizeof(toggle));
	if (ret == -1)
	{
		net_error_out(fd, "net_set_keepalive");
	}
	return ret;
}
Ejemplo n.º 5
0
int net_set_linger(int fd, int toggle)
{
	int ret;
	ret = net_setsockopt(fd, SOL_SOCKET, SO_LINGER, &toggle, sizeof(toggle));
	if (ret == -1)
	{
		net_error_out(fd, "net_set_linger");
	}
	return ret;
}
Ejemplo n.º 6
0
/* NOTE: Possibly only supported on BSD and OSX? */
int net_set_nosigpipe(int fd, int toggle)
{
	int ret = -1;
#ifdef SO_NOSIGPIPE
	ret = net_setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &toggle, sizeof(toggle));
	if (ret == -1)
	{
		net_error_out(fd, "net_set_nosigpipe");
	}
#endif
	return ret;
}
Ejemplo n.º 7
0
int WaitForConnection(int& server_socket)
{
	int addrlen;
	struct sockaddr_in my_name, peer_name;
	int status;

	server_socket = net_socket(AF_INET, SOCK_STREAM, 0);
	if (server_socket == -1)
	{
		printf("Failed to create server socket\n");
	}
	int yes = 1;
	net_setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

	memset(&my_name, 0, sizeof(my_name));
	my_name.sin_family = AF_INET;
	my_name.sin_port = htons(DFF_CONN_PORT);
	my_name.sin_addr.s_addr = htonl(INADDR_ANY);

	status = net_bind(server_socket, (struct sockaddr*)&my_name, sizeof(my_name));
	if (status == -1)
	{
		printf("Failed to bind server socket\n");
	}

	status = net_listen(server_socket, 5); // TODO: Change second parameter..
	if (status == -1)
	{
		printf("Failed to listen on server socket\n");
	}
	printf("Listening now!\n");

	int client_socket = -1;

	struct sockaddr_in client_info;
	socklen_t ssize = sizeof(client_info);
	int new_socket = net_accept(server_socket, (struct sockaddr*)&client_info, &ssize);
	if (new_socket < 0)
	{
		printf("accept failed!\n");
	}
	else
	{
		client_socket = new_socket;
		printf("accept succeeded and returned %d\n", client_socket);
	}

	return client_socket;
}
Ejemplo n.º 8
0
int net_is_ipv6_supported()
{
	if (is_ipv6_supported == -1)
	{
		int ret = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
		if (ret == -1)
		{
#ifdef WINSOCK
			if (net_error() == WSAEAFNOSUPPORT)
#else
			if (net_error() == EAFNOSUPPORT)
#endif
			{
				LOG_TRACE("net_is_ipv6_supported(): IPv6 is not supported on this system.");
				is_ipv6_supported = 0;
				return 0;
			}
			
			net_error_out(ret, "net_is_ipv6_supported");
		}
		else
		{
#ifdef SOCK_DUAL_STACK_OPT
			int off = 0;
			if (net_setsockopt(ret, IPPROTO_IPV6, SOCK_DUAL_STACK_OPT, (char*) &off, sizeof(off)) < 0)
			{
				LOG_ERROR("net_socket_create(): Dual stack IPv6/IPv4 is not supported.");
				is_ipv6_supported = 0;
			}
			else
			{
				is_ipv6_supported = 1;
			}
#else
			is_ipv6_supported = 0;
#endif
			net_close(ret);
		}
	}
	return is_ipv6_supported;
}
Ejemplo n.º 9
0
int net_socket_create(int af, int type, int protocol)
{
	int sd = socket(af, type, protocol);
	if (sd == -1)
	{
		net_error_out(sd, "net_socket_create");
		return -1;
	}

#ifdef SOCK_DUAL_STACK_OPT
	/* BSD style */
	if (af == AF_INET6)
	{
		int off = 0;
		if (net_setsockopt(sd, IPPROTO_IPV6, SOCK_DUAL_STACK_OPT, (char*) &off, sizeof(off)) < 0)
		{
			LOG_ERROR("net_socket_create():  Cannot set socket to dual stack mode IPv6/IPv4 (%d - %s).", net_error(), net_error_string(net_error()));
		}
	}
#endif
	return sd;
}
Ejemplo n.º 10
0
int net_set_recvbuf_size(int fd, size_t size)
{
	return net_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
}
Ejemplo n.º 11
0
int net_set_sendbuf_size(int fd, size_t size)
{
	return net_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
}
Ejemplo n.º 12
0
/* return non zero if error */
static int tcp_open(URLContext *h, const char *uri, int flags)
{
    struct addrinfo hints = { 0 }, *ai, *cur_ai;
    int port, fd = -1;
    TCPContext *s = h->priv_data;
    int listen_socket = 0;
    const char *p;
    char buf[256];
    int ret;
    socklen_t optlen;
    int timeout = 50;
    char hostname[1024],proto[1024],path[1024];
    char portstr[10];

    av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
        &port, path, sizeof(path), uri);
    if (strcmp(proto,"tcp") || port <= 0 || port >= 65536)
        return AVERROR(EINVAL);

    p = strchr(uri, '?');
    if (p) {
        if (av_find_info_tag(buf, sizeof(buf), "listen", p))
            listen_socket = 1;
        if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
            timeout = strtol(buf, NULL, 10);
        }
    }
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    snprintf(portstr, sizeof(portstr), "%d", port);
    ret = getaddrinfo(hostname, portstr, &hints, &ai);
    if (ret) {
        av_log(h, AV_LOG_ERROR,
               "Failed to resolve hostname %s: %s\n",
               hostname, gai_strerror(ret));
        return AVERROR(EIO);
    }

    cur_ai = ai;

 restart:
    ret = AVERROR(EIO);
    fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
    if (fd < 0)
        goto fail;

    if (listen_socket) {
        int fd1;
        int reuse = 1;
        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
        ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
        if (ret) {
            ret = ff_neterrno();
            goto fail1;
        }
        listen(fd, 1);
        fd1 = accept(fd, NULL, NULL);
        if (fd1 < 0) {
            ret = ff_neterrno();
            goto fail1;
        }
        closesocket(fd);
        fd = fd1;
        ff_socket_nonblock(fd, 1);
    } else {
 redo:
  		#ifdef GEKKO
		// turn off Nagle
		u32 nodelay = 1;
		net_setsockopt(cur_ai->ai_family, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
		#endif
        ff_socket_nonblock(fd, 1);
        ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
    }

    if (ret < 0) {
        struct pollfd p = {fd, POLLOUT, 0};
        ret = ff_neterrno();
        if (ret == AVERROR(EINTR)) {
            if (ff_check_interrupt(&h->interrupt_callback)) {
                ret = AVERROR_EXIT;
                goto fail1;
            }
            goto redo;
        }
        if (ret != AVERROR(EINPROGRESS) &&
            ret != AVERROR(EAGAIN))
            goto fail;

        /* wait until we are connected or until abort */
        while(timeout--) {
            if (ff_check_interrupt(&h->interrupt_callback)) {
                ret = AVERROR_EXIT;
                goto fail1;
            }
            ret = poll(&p, 1, 100);
            if (ret > 0)
                break;
        }
        if (ret <= 0) {
            ret = AVERROR(ETIMEDOUT);
            goto fail;
        }
        /* test error */
        optlen = sizeof(ret);
        getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen);
        if (ret != 0) {
            av_log(h, AV_LOG_ERROR,
                   "TCP connection to %s:%d failed: %s\n",
                   hostname, port, strerror(ret));
            ret = AVERROR(ret);
            goto fail;
        }
    }
    h->is_streamed = 1;
    s->fd = fd;
    freeaddrinfo(ai);
    return 0;

 fail:
    if (cur_ai->ai_next) {
        /* Retry with the next sockaddr */
        cur_ai = cur_ai->ai_next;
        if (fd >= 0)
            closesocket(fd);
        goto restart;
    }
 fail1:
    if (fd >= 0)
        closesocket(fd);
    freeaddrinfo(ai);
    return ret;
}
Ejemplo n.º 13
0
static int
connect2Server_with_af(char *host, int port, int af,int verb) {
	int socket_server_fd;
	int err;
        socklen_t err_len;
	int ret,count = 0;
	fd_set set;
	struct timeval tv;
	union {
		struct sockaddr_in four;
#ifdef HAVE_AF_INET6
		struct sockaddr_in6 six;
#endif
	} server_address;
	size_t server_address_size;
	void *our_s_addr;	// Pointer to sin_addr or sin6_addr
	struct hostent *hp=NULL;
	char buf[255];

#if HAVE_WINSOCK2_H
	unsigned long val;
	int to;
#else
	struct timeval to;
#endif

#if HAVE_WINSOCK2_H && defined(HAVE_AF_INET6)
	// our winsock name resolution code can not handle IPv6
	if (af == AF_INET6) {
		mp_msg(MSGT_NETWORK, MSGL_WARN, "IPv6 not supported for winsock2\n");
		return TCP_ERROR_FATAL;
	}
#endif

	socket_server_fd = socket(af, SOCK_STREAM, 0);


	if( socket_server_fd==-1 ) {
//		mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to create %s socket:\n", af2String(af));
		return TCP_ERROR_FATAL;
	}

#if defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO)
#if HAVE_WINSOCK2_H
	/* timeout in milliseconds */
	to = 10 * 1000;
#else
	to.tv_sec = 10;
	to.tv_usec = 0;
#endif
	setsockopt(socket_server_fd, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to));
	setsockopt(socket_server_fd, SOL_SOCKET, SO_SNDTIMEO, &to, sizeof(to));
#endif

	switch (af) {
		case AF_INET:  our_s_addr = (void *) &server_address.four.sin_addr; break;
#ifdef HAVE_AF_INET6
		case AF_INET6: our_s_addr = (void *) &server_address.six.sin6_addr; break;
#endif
		default:
			mp_msg(MSGT_NETWORK,MSGL_ERR, MSGTR_MPDEMUX_NW_UnknownAF, af);
			return TCP_ERROR_FATAL;
	}


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

#if HAVE_INET_PTON
	if (inet_pton(af, host, our_s_addr)!=1)
#elif HAVE_INET_ATON
	if (inet_aton(host, our_s_addr)!=1)
#elif HAVE_WINSOCK2_H
	if ( inet_addr(host)==INADDR_NONE )
#endif
	{
		if(verb) mp_msg(MSGT_NETWORK,MSGL_STATUS,MSGTR_MPDEMUX_NW_ResolvingHostForAF, host, af2String(af));

#ifdef HAVE_GETHOSTBYNAME2
		hp=(struct hostent*)gethostbyname2( host, af );
#else
		hp=(struct hostent*)gethostbyname( host );
#endif
		if( hp==NULL ) {
			if(verb) mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_CantResolv, af2String(af), host);
			return TCP_ERROR_FATAL;
		}

		memcpy( our_s_addr, (void*)hp->h_addr_list[0], hp->h_length );
	}
#if HAVE_WINSOCK2_H
	else {
		unsigned long addr = inet_addr(host);
		memcpy( our_s_addr, (void*)&addr, sizeof(addr) );
	}
#endif

	switch (af) {
		case AF_INET:
			server_address.four.sin_family=af;
			server_address.four.sin_port=htons(port);
			server_address_size = sizeof(server_address.four);
			break;
#ifdef HAVE_AF_INET6
		case AF_INET6:
			server_address.six.sin6_family=af;
			server_address.six.sin6_port=htons(port);
			server_address_size = sizeof(server_address.six);
			break;
#endif
		default:
			mp_msg(MSGT_NETWORK,MSGL_ERR, MSGTR_MPDEMUX_NW_UnknownAF, af);
			return TCP_ERROR_FATAL;
	}

#if HAVE_INET_PTON
	inet_ntop(af, our_s_addr, buf, 255);
#elif HAVE_INET_ATON || defined(HAVE_WINSOCK2_H)
	av_strlcpy( buf, inet_ntoa( *((struct in_addr*)our_s_addr) ), 255);
#endif
	if(verb) mp_msg(MSGT_NETWORK,MSGL_STATUS,MSGTR_MPDEMUX_NW_ConnectingToServer, host, buf , port );

	// Turn the socket as non blocking so we can timeout on the connection
#if defined(GEKKO)
	// turn off Nagle
	u32 nodelay = 1;
	net_setsockopt(socket_server_fd,IPPROTO_TCP,TCP_NODELAY,&nodelay,sizeof(nodelay));

	// net_fcntl(socket_server_fd, F_SETFL, net_fcntl(socket_server_fd, F_GETFL, 0) | IOS_O_NONBLOCK);
	u64 t1,t2;
	t1=ticks_to_millisecs(gettime());
	do {
		ret = net_connect(socket_server_fd,(struct sockaddr*)&server_address,server_address_size);
		t2=ticks_to_millisecs(gettime());
		if(t2-t1 > 8000) break; // 8 secs to try to connect
		usleep(500);
	}while(ret != -EISCONN);
	if(ret != -EISCONN)
	{
		closesocket(socket_server_fd);
		return TCP_ERROR_PORT;
	}
	// net_fcntl(socket_server_fd, F_SETFL, net_fcntl(socket_server_fd, F_GETFL, 0) & ~IOS_O_NONBLOCK);
#elif !HAVE_WINSOCK2_H
	fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK );
#else
	val = 1;
	ioctlsocket( socket_server_fd, FIONBIO, &val );
#endif

#if !defined(GEKKO)
	if( connect( socket_server_fd, (struct sockaddr*)&server_address, server_address_size )==-1 ) {
#if !HAVE_WINSOCK2_H
		if( errno!=EINPROGRESS ) {
#else
		if( (WSAGetLastError() != WSAEINPROGRESS) && (WSAGetLastError() != WSAEWOULDBLOCK) ) {
#endif
			if(verb) mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_CantConnect2Server, af2String(af));
			closesocket(socket_server_fd);
			return TCP_ERROR_PORT;
		}
	}
	tv.tv_sec = 0;
	tv.tv_usec = 500000;
	FD_ZERO( &set );
	FD_SET( socket_server_fd, &set );
	// When the connection will be made, we will have a writeable fd
	while((ret = select(socket_server_fd+1, NULL, &set, NULL, &tv)) == 0) {
	      if(count > 30 || stream_check_interrupt(500)) {
		if(count > 30)
		  mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_ConnTimeout);
		else
		  mp_msg(MSGT_NETWORK,MSGL_V,"Connection interrupted by user\n");
		return TCP_ERROR_TIMEOUT;
	      }
	      count++;
	      FD_ZERO( &set );
	      FD_SET( socket_server_fd, &set );
	      tv.tv_sec = 0;
	      tv.tv_usec = 500000;
	}
	if (ret < 0) mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_SelectFailed);

	// Turn back the socket as blocking
#if !HAVE_WINSOCK2_H
	// fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) & ~O_NONBLOCK );
#else
	val = 0;
	ioctlsocket( socket_server_fd, FIONBIO, &val );
#endif
	// Check if there were any errors
	err_len = sizeof(int);
	ret =  getsockopt(socket_server_fd,SOL_SOCKET,SO_ERROR,&err,&err_len);
	if(ret < 0) {
		mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_GetSockOptFailed,strerror(errno));
		return TCP_ERROR_FATAL;
	}
	if(err > 0) {
		mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_ConnectError,strerror(err));
		return TCP_ERROR_PORT;
	}
#endif

	return socket_server_fd;
}

// Connect to a server using a TCP connection
// return -2 for fatal error, like unable to resolve name, connection timeout...
// return -1 is unable to connect to a particular port


int
connect2Server(char *host, int  port, int verb) {
#ifdef HAVE_AF_INET6
	int r;
	int s = TCP_ERROR_FATAL;

	r = connect2Server_with_af(host, port, network_prefer_ipv4 ? AF_INET:AF_INET6,verb);
	if (r >= 0) return r;

	s = connect2Server_with_af(host, port, network_prefer_ipv4 ? AF_INET6:AF_INET,verb);
	if (s == TCP_ERROR_FATAL) return r;
	return s;
#else
	return connect2Server_with_af(host, port, AF_INET,verb);
#endif


}
Ejemplo n.º 14
0
static bool StartWiiLoadServer (void)
	{
	struct sockaddr_in sin;
	struct sockaddr_in client_address;
	s32 connection;
	int err;
	
	if ( wiiload.status == WIILOAD_HBREADY || wiiload.status == WIILOAD_HBZREADY)
		{
		// This isn't an error, simply we have received valid data. Host process should set hbready mode to IDLE or stop/restart the thread
		return true;
		}

	// Clean old data, if any
	if (wiiload.args) free (wiiload.args);
	
	wiiload.args = NULL;
	wiiload.argl = 0;
	
	printopt ("StartWiiLoadServer begin");
	
	socklen_t addrlen = sizeof(client_address);

	//Open socket
	socket = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	if (socket == INVALID_SOCKET)
		{
		printopt ("net_socket INVALID_SOCKET");
		return false;
		}

	int one = 1;
	err = net_setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one));
	if (err < 0)
		{
		printopt ("net_setsockopt %d");
		return false;
		}
	
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = htonl(INADDR_ANY);

	int flags = net_fcntl(socket, F_GETFL, 0);
	flags = net_fcntl(socket, F_SETFL, flags|4); // Set non blocking

	err = net_bind(socket, (struct sockaddr*)&sin, sizeof(sin));
	if (err < 0)
		{
		printopt ("net_bind error %d", err);
		net_close(socket);
		return false;
		}

	if (net_listen(socket, 10) < 0)
		{
		printopt ("net_listen error");
		net_close(socket);
		return false;
		}
	
	printopt ("net_accept");
	
	// WIILOAD_IDLE is set once. This because if an hb is executed it make no sense....
	// Maybe it can be usefull for an app is an hb is rejected. Hosting appl. can set it by itsel
	
	wiiload.status = WIILOAD_IDLE;

	do
		{
		int i;
		
		for (i = 0; i < 10; i++)
			{
			usleep (50000);
			if (pauseWiiload) break;
			}
		
		if (pauseWiiload)
			{
			Debug ("WiiLoad thread paused");
			pauseWiiload = 2;
			do
				{
				usleep (250*1000);
				}
			while (pauseWiiload && !stopNetworkThread);
			Debug ("WiiLoad thread resumed");
			pauseWiiload = 0;
			}
		
		connection = net_accept(socket, (struct sockaddr*)&client_address, &addrlen);
		if (connection >= 0)
			{
			sprintf(wiiload.op, "%s", inet_ntoa(client_address.sin_addr));
			if (!WiiLoad (connection))
				{
				wiiload.status = WIILOAD_IDLE;
				}
			net_close(connection);
			}
			
		usleep (100);
		}
	while (!stopNetworkThread);
	
	net_close(socket);
	
	return true;
	}