コード例 #1
0
/*! \internal

    Sets the port and address to a sockaddr. Requires that sa point to the IPv6 struct if the address is IPv6.
*/
static inline void qt_socket_setPortAndAddress(SOCKET socketDescriptor, sockaddr_in * sockAddrIPv4, qt_sockaddr_in6 * sockAddrIPv6,
                                               quint16 port, const QHostAddress & address, sockaddr ** sockAddrPtr, QT_SOCKLEN_T *sockAddrSize)
{
#if !defined(QT_NO_IPV6)
    if (address.protocol() == QAbstractSocket::IPv6Protocol) {
        memset(sockAddrIPv6, 0, sizeof(qt_sockaddr_in6));
        sockAddrIPv6->sin6_family = AF_INET6;
        sockAddrIPv6->sin6_scope_id = address.scopeId().toInt();
        WSAHtons(socketDescriptor, port, &(sockAddrIPv6->sin6_port));
        Q_IPV6ADDR tmp = address.toIPv6Address();
        memcpy(&(sockAddrIPv6->sin6_addr.qt_s6_addr), &tmp, sizeof(tmp));
        *sockAddrSize = sizeof(qt_sockaddr_in6);
        *sockAddrPtr = (struct sockaddr *) sockAddrIPv6;
    } else
#endif
    if (address.protocol() == QAbstractSocket::IPv4Protocol
        || address.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
        memset(sockAddrIPv4, 0, sizeof(sockaddr_in));
        sockAddrIPv4->sin_family = AF_INET;
        WSAHtons(socketDescriptor, port, &(sockAddrIPv4->sin_port));
        WSAHtonl(socketDescriptor, address.toIPv4Address(), &(sockAddrIPv4->sin_addr.s_addr));
        *sockAddrSize = sizeof(sockaddr_in);
        *sockAddrPtr = (struct sockaddr *) sockAddrIPv4;
    } else {
        // unreachable
    }
}
コード例 #2
0
void  WinTCPSocketServer::configSocket(unsigned short port)
{
  sockaddr_in	service;
  hostent*	thisHost;
  char		hostName[255];
  char*		ip;

  service.sin_family = AF_INET;
  WSAHtons(this->_sock, port, &service.sin_port);
  gethostname(hostName, 255);
  if (!(thisHost = gethostbyname(hostName)))
    throw WSAException("TCPSocketServer: gethostbyname");
  ip = inet_ntoa(*(struct in_addr *)*thisHost->h_addr_list);
  service.sin_addr.s_addr = INADDR_ANY;
  if (bind(this->_sock, (SOCKADDR*) &service, sizeof(SOCKADDR)) == SOCKET_ERROR)
  {
    int	code = WSAGetLastError();

    if (closesocket(this->_sock) == SOCKET_ERROR)
      throw WSAException("TCPSocketServer: closesocket");
    throw WSAException("TCPSocketServer: bind", code);
  }
  if (listen(this->_sock, 20) == SOCKET_ERROR)
  {
    int	code = WSAGetLastError();

    if (closesocket(this->_sock) == SOCKET_ERROR)
      throw WSAException("TCPSocketServer: closesocket");
    throw WSAException("TCPSocketServer: listen", code);
  }
}
コード例 #3
0
ファイル: TCPWinServSocket.cpp プロジェクト: smootise/R-Type
bool		TCPWinServSocket::Connect(int port, Selector &sel)
{
	struct sockaddr_in    s_in;
	u_short				  ret;

	// Socket creation
	_fathersocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, NULL, WSA_FLAG_OVERLAPPED);
	if (_fathersocket == INVALID_SOCKET)
		return (false);
	//Socket binding
	s_in.sin_family = AF_INET;
	s_in.sin_addr.s_addr = INADDR_ANY;
	if ((WSAHtons(_fathersocket, port, &ret)) == SOCKET_ERROR)
		return (false);
	
	s_in.sin_port = ret;
	if ((bind(_fathersocket, (const struct sockaddr *)&s_in, sizeof(s_in))) == SOCKET_ERROR)
		return (false);

	//Socket listening
	if ((listen(_fathersocket, SOMAXCONN)) == SOCKET_ERROR)
		return (false);
	//Add to selector for monitoring
	sel.Add_to_checkread(_fathersocket);
	return (true);
}
コード例 #4
0
ファイル: WinSocketUdp.cpp プロジェクト: fiahil/R-Type
void SocketUdp::Send(const std::string& packet)
{
	SOCKADDR_IN sin;

	DEBUG << "Sending in progress" << std::endl;
	for (std::list<EndPoint*>::iterator it = this->client_.begin() ; it != this->client_.end() ; ++it) { 
		sin.sin_family = AF_INET;
		sin.sin_addr.s_addr = inet_addr((*it)->getIpStr().c_str());
		WSAHtons(this->socket_, (*it)->getPort(), &sin.sin_port);

		WSABUF* fb = new WSABUF();
		CHAR* buffer = new CHAR[sizeof(UDPPacket)];
		PackManUDP::Memcpy(buffer, packet.data(), packet.size());
		fb->buf = buffer;
		fb->len = sizeof(UDPPacket);

		DWORD sended = 0;

		if (WSASendTo(this->socket_, fb, 1, &sended, 0, reinterpret_cast<struct sockaddr*>(&sin), sizeof(sin), 0, 0) == SOCKET_ERROR)
			throw ErrorInOut("Cannot send data");
		DEBUG << "Sending completed" << std::endl;

		delete fb;
		delete buffer;
	}
}
コード例 #5
0
GSocketUdpServer::GSocketUdpServer(unsigned int port, unsigned int maxConnexion)
{
	this->_port = port;
	this->_maxConnexion = maxConnexion;
#if defined (GWIN)
	WSADATA	wsaData;
	if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
	{
		GWarning::Warning("GSocketUdpServer", "GSocketUdpServer(unsigned int port, unsigned int max)", "Error WSAStartup()");
		throw GException("GSocketUdpServer", "Error WSAStartup() !");
	}
	this->_socket = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
	if (this->_socket == INVALID_SOCKET)
	{
		GWarning::Warning("GSocketTcpServer", "GSocketTcpServer(unsigned int port, unsigned int max)", "Error WSASocket()");
		throw GException("GSocketUdpServer", "Error WSASocket()");
	}
	this->_sockaddr.sin_family = AF_INET;
	this->_sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	if (WSAHtons(this->_socket, this->_port, &this->_sockaddr.sin_port) == SOCKET_ERROR)
	{
		GWarning::Warning("GSocketTcpServer", "GSocketTcpServer(unsigned int port, unsigned int max)", "Error WSAHtons()");
		throw GException("GSocketUdpServer", "Error WSAHtons()");
	}
	if (WSAHtonl(this->_socket, INADDR_ANY, &this->_sockaddr.sin_addr.s_addr) == SOCKET_ERROR)
	{
		GWarning::Warning("GSocketTcpServer", "GSocketTcpServer(unsigned int port, unsigned int max)", "Error WSAHtons()");
		throw GException("GSocketTcpServer", "Error in WSAHtonl()");
	}
	sockaddr_in	s_port;
	socklen_t len = sizeof(s_port);
	if (bind(this->_socket, reinterpret_cast <sockaddr*> (&this->_sockaddr), sizeof(this->_sockaddr)) == SOCKET_ERROR) 
	{
		closesocket(this->_socket);
		throw GException("GSocketTcpServer", "bind() failed.");
	}
	if (getsockname(this->_socket, (SOCKADDR*)&s_port, &len) < 0)
	{
		closesocket(this->_socket);
		throw GException("GSocketTcpServer", "Error sockname");
	}
#else
	if ((int)(this->_socket = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
	{
		this->_lastError = GSocketUdpServer::ERROR_SOCKET;
		throw GException("GSocketUdpServer", "Error socket()");
	}
	this->_sockaddr.sin_family = AF_INET;
	this->_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	this->_sockaddr.sin_port = htons(this->_port);
	if (bind(this->_socket,(sockaddr *) &(this->_sockaddr), sizeof (this->_sockaddr)) == SOCKET_ERROR)
	{
		this->_lastError = GSocketTcpServer::ERROR_SOCKET;
		throw GException("GSocketTcpServer", "Error bind");
	}
#endif
}
コード例 #6
0
ファイル: windowsoutpost.cpp プロジェクト: alerque/bibledit
void windowsoutpost_open_url(const ustring & url)
// This function supposes that the Bibledit Windows Outpost already runs.
// It commands the outpost to open "url", a .pdf file or .html, etc.
{
  struct sockaddr_in address;
  struct hostent *host;
  int sock;

  // DD: Shouldn't this use the outpost defined by the user?
  host = gethostbyname("localhost");
  if (host) {
#ifdef WIN32
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) != SOCKET_ERROR)
#else
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) >= 0)
#endif
    {
      address.sin_family = AF_INET;
      memcpy(&address.sin_addr, host->h_addr_list[0], sizeof(address.sin_addr));
#ifdef WIN32
      WSAHtons(sock, 51515, &address.sin_port);
      if (connect(sock, (struct sockaddr *)&address, sizeof(address)) == SOCKET_ERROR)
#else
      address.sin_port = htons(51515);
      if (connect(sock, (struct sockaddr *)&address, sizeof(address)))
#endif
      {
        cerr << _("Cannot connect to Windows Outpost") << endl;
#ifdef WIN32
        closesocket(sock);
#else
        close(sock);
#endif
      } else {
        ustring command = "open " + url + "\n";
		DEBUG(command)
#ifdef WIN32
        u_long socketmode = 1; // Set non-blocking
        ioctlsocket(sock, FIONBIO, &socketmode);
        if (send(sock, command.c_str(), command.length(), 0)) ;
#else
        fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
        if (write(sock, command.c_str(), command.length())) ;
#endif
        cout << _("Outpost opens ") << url << endl;
      }
    } else {
      cout << _("No socket available") << endl;
    }
  } else {
    cout << _("Error looking up hostname") << endl;
  }
}
コード例 #7
0
ファイル: ServerSocket.cpp プロジェクト: isuker/NetWorkCode
	bool CServerSocket::ActiveStart()
	{
		HANDLE hIOCPHandle;
		sockaddr_in addr;
		m_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0);
		if(m_hIOCP!=0)
		{
			m_IOCPSOCKET.socket = WSASocket(PF_INET,SOCK_STREAM,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);
			if(m_IOCPSOCKET.socket != INVALID_SOCKET)
			{
				memset(&addr,0,sizeof(sockaddr_in));
				addr.sin_family = PF_INET;
				if(strcmp(m_IOCPSOCKET.ip,"0.0.0.0")==0)
				{
					addr.sin_addr.S_un.S_addr = INADDR_ANY;

				}
				else
				{
					addr.sin_addr.S_un.S_addr = inet_addr(m_IOCPSOCKET.ip);
				}
				WSAHtons(m_IOCPSOCKET.socket,m_IOCPSOCKET.port,&addr.sin_port);
				//°ó¶¨Socket
				if(bind(m_IOCPSOCKET.socket,(sockaddr*)&addr,sizeof(sockaddr_in))==0)
				{
					m_AcceptThread = new CAcceptThread(this);
					m_AcceptThread->Resume();
					for (int i = 0 ;i<= m_iWorkThreadCount ;i++)
					{
						m_WorkThread[i] = new CWorkThread(this,false);
					}
					return true;

				}
				else
				{
					this->OnError(NULL,GetLastError());
					closesocket(m_IOCPSOCKET.socket);
					m_IOCPSOCKET.socket = INVALID_SOCKET;
				}
			}//endif
			else
			{
				OnError(NULL,WSAGetLastError());			
				hIOCPHandle = m_hIOCP;
				m_hIOCP = 0 ;
				CloseHandle(m_hIOCP);
			}
		}
		else
			OnError(NULL,GetLastError());
			return false;
	}
コード例 #8
0
ファイル: CWSocket.cpp プロジェクト: Daypi/DaltoBabel
void		CWSocket::connect(const char *ipAddress, int port)
{
	sockaddr_in			server_info;

	if (this->_func != ISocket::NONE)
		throw Exception(((this->_func == ISocket::SERVER) ? ("this socket is server socket.") : ("this socket is already connected to server.")));
	server_info.sin_family = AF_INET;
	server_info.sin_addr.s_addr = inet_addr(ipAddress);
	WSAHtons(this->_sock, port, &server_info.sin_port);
	this->_func = ISocket::CLIENT;
	if (WSAConnect(this->_sock, (SOCKADDR *)&server_info, sizeof(server_info), NULL, NULL, NULL, NULL) != 0)
		throw Exception("WSAConnect has failed.");
}
コード例 #9
0
ファイル: CWSocket.cpp プロジェクト: Daypi/DaltoBabel
void		CWSocket::bind(int port)
{
	sockaddr_in			service;

	if (this->_func != ISocket::NONE)
		throw Exception(((this->_func == ISocket::CLIENT) ? ("this socket is client socket.") : ("this socket is already bind to server.")));
	service.sin_family = AF_INET;
	service.sin_addr.s_addr = INADDR_ANY;
	WSAHtons(this->_sock, port, &service.sin_port);
	this->_func = ISocket::SERVER;
	if (::bind(this->_sock, (SOCKADDR *)&service, sizeof(service)) != 0)
		throw Exception("bind has failed.");
}
コード例 #10
0
ファイル: WinSocketUdp.cpp プロジェクト: fiahil/R-Type
void SocketUdp::Bind(const EndPoint& ep)
{
	SOCKADDR_IN	sin;

	if (!ep.getIp())
		 WSAHtonl(this->socket_, INADDR_ANY, &sin.sin_addr.s_addr);
	else
		sin.sin_addr.s_addr = inet_addr(ep.getIpStr().c_str());
	sin.sin_family = AF_INET;
	WSAHtons(this->socket_, ep.getPort(), &sin.sin_port);
	if ((bind(this->socket_, reinterpret_cast<SOCKADDR*>(&sin), sizeof sin)) == SOCKET_ERROR)
		throw ErrorInit("Cannot bind the socket");
}
コード例 #11
0
ファイル: windowsoutpost.cpp プロジェクト: alerque/bibledit
void WindowsOutpost::telnet(const ustring & hostname)
{
  // If the computer address can be converted to an IP, do so. 
  // If not, try to look it up in DNS.
  host = gethostbyname(hostname.c_str());
  if (host) {
    // We got the host, now get a socket.
#ifdef WIN32
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)
#else
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) >= 0)
#endif
    {
      // We've got the socket, now set some variables.
      address.sin_family = AF_INET;
      // Take the first IP address associated with this hostname.
      memcpy(&address.sin_addr, host->h_addr_list[0], sizeof(address.sin_addr));
      // Now connect.
#ifdef WIN32
      WSAHtons(sock, 51515, &address.sin_port);
      if (connect(sock, (struct sockaddr *)&address, sizeof(address)) == SOCKET_ERROR)
#else
      address.sin_port = htons(51515);
      if (connect(sock, (struct sockaddr *)&address, sizeof(address)))
#endif
      {
        log(_("No connection possible"));
#ifdef WIN32
      	closesocket(sock);
#else
        close(sock);
#endif
      } else {
        // We've a connection. Set the socket to non-blocking mode.
#ifdef WIN32
        u_long socketmode = 1; // Set non-blocking
        ioctlsocket(sock, FIONBIO, &socketmode);
#else
        fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
#endif
        log(_("Connected"));
        connected = true;
      }
    } else {
      log(_("No socket available"));
    }
  } else {
    /* We can't find an IP number */
    log(_("Error looking up hostname"));
  }
}
コード例 #12
0
ファイル: windowsoutpost.cpp プロジェクト: alerque/bibledit
bool windowsoutpost_telnet(const ustring & hostname)
// This makes a connection with the Outpost on "host" and then disconnects again.
// It returns true if this worked out.
{
  bool success = false;
  struct sockaddr_in address;
  struct hostent *host;
  int sock;
  host = gethostbyname(hostname.c_str());
  if (host) {
#ifdef WIN32
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) != SOCKET_ERROR)
#else
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) >= 0)
#endif
    {
      address.sin_family = AF_INET;
      memcpy(&address.sin_addr, host->h_addr_list[0], sizeof(address.sin_addr));
#ifdef WIN32
      WSAHtons(sock, 51515, &address.sin_port);
      if (connect(sock, (struct sockaddr *)&address, sizeof(address)) == SOCKET_ERROR)
#else
      address.sin_port = htons(51515);
      if (connect(sock, (struct sockaddr *)&address, sizeof(address)))
#endif
      {
        ; // success = false;
      } else {
        success = true;
      }
#ifdef WIN32
      closesocket(sock);
#else
      close(sock);
#endif
    }
  }
  return success;
}
コード例 #13
0
ファイル: UDPWinSocket.cpp プロジェクト: smootise/R-Type
bool	UDPWinSocket::Connect(int port)
{
	u_short				rethtons;
	std::vector<int>	separated_ip(4, 0);
	size_t				dot_pos;
	int					i = 0;
	int					pos_start = 0;
	int					pos_end = 0;

	dot_pos = -1;
	// on decoupe l'ip en 4 int !
	while ((dot_pos = _ipsource.find(".", dot_pos + 1)) != std::string::npos)
	{
		if (i > 3)
		{
			std::cerr << "invalid ip address : only ipv4 is supported by this prog" << std::endl;
			return (false);
		}
		pos_end = dot_pos;
		separated_ip[i] = atoi(_ipsource.substr(pos_start, pos_end - pos_start).c_str());
		pos_start = pos_end + 1;
		i++;
	}
	separated_ip[3] = atoi(_ipsource.substr(pos_start).c_str());
	std::cout << "ip : " << separated_ip[0] << "." << separated_ip[1] << "." << separated_ip[2] << "." << separated_ip[3] << std::endl;

	/* Open a datagram socket */
	if ((_socket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0, NULL, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
	{
		std::cerr << "couldn't create the socket" << std::endl;
		return (false);
	}
	/* Clear out server struct */
	memset((void *)&_server, '\0', sizeof(struct sockaddr_in));
	/* Set family and port */
	_server.sin_family = AF_INET;
	WSAHtons(_socket, port, &rethtons);
	_server.sin_port = rethtons;
	/* Set server address */
	_server.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)(separated_ip.at(0));
	_server.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)(separated_ip.at(1));
	_server.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)(separated_ip.at(2));
	_server.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)(separated_ip.at(3));

	/* Clear out client struct */
	memset((void *)&_client, '\0', sizeof(struct sockaddr_in));
	/* Set family and port */
	_client.sin_family = AF_INET;
	WSAHtons(_socket, 0, &rethtons);
	_client.sin_port = rethtons;
	_client.sin_addr.s_addr = htonl(INADDR_ANY);

	/* Bind local address to socket */
	if (bind(_socket, (struct sockaddr *)&_client, sizeof(struct sockaddr_in)) == -1)
	{
		std::cerr << "could'nt bind the socket" << std::endl;
		return (false);
	}

	// set socket to non-blocking
	unsigned long			mode = 1;
	if ((ioctlsocket(_socket, FIONBIO, &mode)) == SOCKET_ERROR)
	{
		std::cerr << "couldn't set socket to non bloking mode " << std::endl;
		return (false);
	}
	_connected = true;
	return (true);
} 
コード例 #14
0
/*!
  Listen a port with SO_REUSEADDR option.
  This function must be called in a tfserver process.
 */
int TApplicationServer::nativeListen(const QHostAddress &address, quint16 port, OpenFlag)
{
    int protocol = (address.protocol() == QAbstractSocket::IPv6Protocol) ? AF_INET6 : AF_INET;
    SOCKET sock = ::WSASocket(protocol, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
    if (sock == INVALID_SOCKET) {
        tSystemError("WSASocket Error: %d", WSAGetLastError());
        return -1;
    }
    
    // ReuseAddr
    bool on = true;
    if (::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) != 0) {
        tSystemError("setsockopt error: %d", WSAGetLastError());
        goto error_socket;
    }
    
    if (address.protocol() == QAbstractSocket::IPv6Protocol) {
        struct tf_in6_addr {
            quint8 tf_s6_addr[16];
        };
        struct tf_sockaddr_in6 {
            short   sin6_family;            /* AF_INET6 */
            quint16 sin6_port;              /* Transport level port number */
            quint32 sin6_flowinfo;          /* IPv6 flow information */
            struct  tf_in6_addr sin6_addr;  /* IPv6 address */
            quint32 sin6_scope_id;          /* set of interfaces for a scope */
        } sa6;
        
        memset(&sa6, 0, sizeof(sa6));
        sa6.sin6_family = AF_INET6;
        WSAHtons(sock, port, &(sa6.sin6_port));
        Q_IPV6ADDR ipv6 = address.toIPv6Address();
        memcpy(&(sa6.sin6_addr.tf_s6_addr), &ipv6, sizeof(ipv6));
        if (::bind(sock, (struct sockaddr *)&sa6, sizeof(sa6)) != 0) {
            tSystemError("bind(v6) error: %d", WSAGetLastError());
            goto error_socket;
        }
        
    } else if (address.protocol() == QAbstractSocket::IPv4Protocol
#if QT_VERSION >= 0x050000
               || address.protocol() == QAbstractSocket::QAbstractSocket::AnyIPProtocol
#endif
        ) {
        struct sockaddr_in sa;
        memset(&sa, 0, sizeof(sa));
        sa.sin_family = AF_INET;
        WSAHtons(sock, port, &(sa.sin_port));
        WSAHtonl(sock, address.toIPv4Address(), &(sa.sin_addr.s_addr));
        if (::bind(sock, (struct sockaddr *)&sa, sizeof(sa)) != 0) {
            tSystemError("bind error: %d", WSAGetLastError());
            goto error_socket;
        }
    } else {  // UnknownNetworkLayerProtocol
        goto error_socket;
    }
    
    if (::listen(sock, 50) != 0) {
        tSystemError("listen error: %d", WSAGetLastError());
        goto error_socket;
    }
    return sock;

error_socket:
    nativeClose(sock);
    return -1;
}
コード例 #15
0
ファイル: master_proto.cpp プロジェクト: yrro/qarma
__stdcall unsigned int master_proto (void* _args) {
	master_proto_args args = *reinterpret_cast<master_proto_args*> (_args);

	PostMessage (args.hwnd, qm_master_begin, args.id, 0);

	std::unique_ptr<addrinfo, decltype(&freeaddrinfo)> lookup (nullptr, freeaddrinfo);
	{
		std::default_random_engine reng (std::chrono::system_clock::now ().time_since_epoch ().count ());
		std::uniform_int_distribution<> rdist (0, 19);
		std::ostringstream host;
		host << "arma2oapc.ms" << rdist (reng) << ".gamespy.com";

		addrinfo hints = addrinfo ();
		hints.ai_family = AF_INET;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_protocol = IPPROTO_TCP;
		addrinfo* tmp;
		int r = getaddrinfo (host.str ().c_str (), "28910", &hints, &tmp); // TODO load balance
		if (r) {
			SendMessage (args.hwnd, qm_master_error, args.id, reinterpret_cast<LPARAM> (wstrerror (WSAGetLastError ()).c_str ()));
			return 0;
		}
		lookup.reset (tmp);
	}

	qsocket socket {lookup->ai_family, lookup->ai_socktype, lookup->ai_protocol};
	if (socket == INVALID_SOCKET) {
		SendMessage (args.hwnd, qm_master_error, args.id, reinterpret_cast<LPARAM> (wstrerror (WSAGetLastError ()).c_str ()));
		return 0;
	}

	int r = connect (socket, lookup->ai_addr, lookup->ai_addrlen);
	if (r == SOCKET_ERROR) {
		SendMessage (args.hwnd, qm_master_error, args.id, reinterpret_cast<LPARAM> (wstrerror (WSAGetLastError ()).c_str ()));
		return 0;
	}

	// transmit request
	std::array<unsigned char, 9> master_validate;
	enctypex_decoder_rand_validate (&master_validate[0]);
	{
		std::ostringstream packet;
		packet << '\0'
			   << '\1'
			   << '\3'
			   << '\0' // 32-bit
			   << '\0'
			   << '\0'
			   << '\0'
			   << "arma2oapc" << '\0'
			   << "gslive" << '\0';
		std::copy (master_validate.begin (), master_validate.end () - 1, std::ostreambuf_iterator<char> (packet)); // note: don't copy the final '\0' byte of master_validate
		packet << "" << '\0' // filter (note, not preceeded by a '\0' separator either
			   << REQUEST << '\0'
			   << '\0'
			   << '\0'
			   << '\0'
			   << '\1'; // 1 = requested information
		std::vector<char> buf (2 + packet.str ().size ());
		WSAHtons (socket, buf.size (), reinterpret_cast<u_short*> (&buf[0]));
		const std::string s = packet.str ();
		std::copy (s.begin (), s.end (), 2 + buf.begin ());

		int r = send (socket, &buf[0], buf.size (), 0);
		if (r == SOCKET_ERROR) {
			SendMessage (args.hwnd, qm_master_error, args.id, reinterpret_cast<LPARAM> (wstrerror (WSAGetLastError ()).c_str ()));
			return 0;
		} else if (r != static_cast<int> (buf.size ())) {
			PostMessage (args.hwnd, qm_master_error, args.id, reinterpret_cast<LPARAM> (L"short send"));
			return 0;
		}
	}
	shutdown (socket, SD_SEND); // XXX error check

	// read response
	enctypex_data_t enctypex_data;
	enctypex_data.start = 0;
	std::vector<unsigned char> data;
	data.reserve (16384);
	while (true) {
		std::array<char, 8192> buf;
		int r = recv (socket, &buf[0], buf.size (), 0);
		if (r == SOCKET_ERROR) {
			SendMessage (args.hwnd, qm_master_error, args.id, reinterpret_cast<LPARAM> (wstrerror (WSAGetLastError ()).c_str ()));
			return 0;
		} else if (r == 0) {
			PostMessage (args.hwnd, qm_master_error, args.id, reinterpret_cast<LPARAM> (L"short recv"));
			return 0;
		}
		std::copy (buf.begin (), buf.begin () + r, std::back_inserter (data));
		PostMessage (args.hwnd, qm_master_progress, args.id, data.size ());

		int len = data.size ();
		unsigned char* endp = enctypex_decoder (reinterpret_cast<unsigned char*> (const_cast<char*> ("Xn221z")), &master_validate[0], &data[0], &len, &enctypex_data);
		assert (endp);
		if (endp && enctypex_decoder_convert_to_ipport (endp, data.size () - (reinterpret_cast<unsigned char*> (endp) - &data[0]), nullptr, nullptr, 0, 0)) {
			break;
		}
	}
	shutdown (socket, SD_RECEIVE); // XXX handle errors

	static_assert (sizeof (server_endpoint) == 6, "server_endpoint is a weird size");
	{
		std::vector<server_endpoint> decoded_data (data.size () / 5); // XXX size seems like a bit of a guess!
		int len = enctypex_decoder_convert_to_ipport (&data[0] + enctypex_data.start, data.size () - enctypex_data.start, reinterpret_cast<unsigned char*> (decoded_data.data ()), nullptr, 0, 0);
		assert (len >= 0); // XXX handle (see gsmyfunc.h line 715)
		for (auto ep: decoded_data)
			SendMessage (args.hwnd, qm_master_found, args.id, reinterpret_cast<LPARAM> (&ep));
	}

	PostMessage (args.hwnd, qm_master_complete, args.id, 0);
	return 0;
}