Example #1
0
static gchar *
socket_last_error_message (void)
{
#ifdef G_OS_WIN32
  int errorcode = WSAGetLastError ();
  wchar_t buf[1024];
  DWORD result =
      FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL, errorcode, 0, (LPSTR) buf, sizeof (buf) / sizeof (wchar_t), NULL);
  if (FAILED (result)) {
    return g_strdup ("failed to get error message from system");
  } else {
    gchar *res =
        g_convert ((gchar *) buf, -1, "UTF-16", "UTF-8", NULL, NULL, NULL);
    /* g_convert() internally calls windows functions which reset the
       windows error code, so fix it up again like this */
    WSASetLastError (errorcode);
    return res;
  }
#else
  return g_strdup (g_strerror (errno));
#endif
}
Example #2
0
// sends all data or throws an exception
void Socket::send( const char * data , int len, const char *context ) {
    while( len > 0 ) {
        int ret = -1;
        if (MONGO_FAIL_POINT(throwSockExcep)) {
#if defined(_WIN32)
            WSASetLastError(WSAENETUNREACH);
#else
            errno = ENETUNREACH;
#endif
            handleSendError(ret, context);
        }
        else {
            ret = _send(data, len, context);
        }

        _bytesOut += ret;

        fassert(16507, ret <= len);
        len -= ret;
        data += ret;

    }
}
Example #3
0
    void Socket::recv( char * buf , int len ) {
        while( len > 0 ) {
            int ret = -1;
            if (MONGO_FAIL_POINT(throwSockExcep)) {
#if defined(_WIN32)
                WSASetLastError(WSAENETUNREACH);
#else
                errno = ENETUNREACH;
#endif
                if (ret <= 0) {
                    handleRecvError(ret, len);
                    continue;
                }
            }
            else {
                ret = unsafe_recv(buf, len);
            }

            fassert(16508, ret <= len);
            len -= ret;
            buf += ret;
        }
    }
Example #4
0
BOOL CAsyncSocket::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
{
	SOCKADDR_IN sockAddr;
	memset(&sockAddr,0,sizeof(sockAddr));

#ifdef _UNICODE
	LPSTR lpszAscii = ConvertUnicodeToAnsi(lpszSocketAddress);
#else
	LPCSTR lpszAscii = lpszSocketAddress;
#endif

	sockAddr.sin_family = AF_INET;

	if (lpszAscii == NULL)
		sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	else
	{
		DWORD lResult = inet_addr(lpszAscii);
	 	if (lResult == INADDR_NONE)
		{
#ifdef _UNICODE
			delete[] lpszAscii;
#endif
			WSASetLastError(WSAEINVAL);
			return FALSE;
		}
		sockAddr.sin_addr.s_addr = lResult;
	}

	sockAddr.sin_port = htons((u_short)nSocketPort);

#ifdef _UNICODE
	delete[] lpszAscii;
#endif
	
	return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
//-----------------------------------------------------------------------------
// Purpose: Open a TCP socket & connect to a given server
// Input  : *pServerName - server name (text or ip)
//			port - port number of the server
// Output : HSOCKET
//-----------------------------------------------------------------------------
HSOCKET SocketOpen( const char *pServerName, int port )
{
	SOCKADDR_IN sockAddr;
	SOCKET s;

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

	s = socket( AF_INET, SOCK_STREAM, 0 );

	sockAddr.sin_family = AF_INET;
	sockAddr.sin_addr.s_addr = inet_addr(pServerName);

	if (sockAddr.sin_addr.s_addr == INADDR_NONE)
	{
		LPHOSTENT lphost;
		lphost = gethostbyname(pServerName);
		if (lphost != NULL)
		{
			sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
		}
		else
		{
			WSASetLastError(WSAEINVAL);
			return FALSE;
		}
	}

	sockAddr.sin_port = htons((u_short)port);

	if ( connect( s, (SOCKADDR *)&sockAddr, sizeof(sockAddr) ) == SOCKET_ERROR )
	{
//		printf("Socket error:%d\n", WSAGetLastError()) ;
		return NULL;
	}

	return (HSOCKET)s;
}
Example #6
0
void *
pthread_getspecific(pthread_key_t key)
/*
 * ------------------------------------------------------
 * DOCPUBLIC
 *      This function returns the current value of key in the
 *      calling thread. If no value has been set for 'key' in
 *      the thread, NULL is returned.
 *
 * PARAMETERS
 *      key
 *              an instance of pthread_key_t
 *
 *
 * DESCRIPTION
 *      This function returns the current value of key in the
 *      calling thread. If no value has been set for 'key' in
 *      the thread, NULL is returned.
 *
 * RESULTS
 *              key value or NULL on failure
 *
 * ------------------------------------------------------
 */
{
	void * ptr;
	if (key == NULL)
		ptr = NULL;
	else {
		int lasterror = GetLastError();
		int lastWSAerror = WSAGetLastError();
		ptr = TlsGetValue(key->key);
		SetLastError(lasterror);
		WSASetLastError(lastWSAerror);
	}
	return ptr;
}
Example #7
0
static int rdg_bio_read(BIO* bio, char* buf, int size)
{
	int status;
	rdpRdg* rdg = (rdpRdg*) BIO_get_data(bio);
	status = rdg_read_data_packet(rdg, (BYTE*) buf, size);

	if (status < 0)
	{
		BIO_clear_retry_flags(bio);
		return -1;
	}
	else if (status == 0)
	{
		BIO_set_retry_read(bio);
		WSASetLastError(WSAEWOULDBLOCK);
		return -1;
	}
	else
	{
		BIO_set_flags(bio, BIO_FLAGS_READ);
	}

	return status;
}
Example #8
0
int
system_errno (gnutls_transport_ptr p)
{
  int tmperr = WSAGetLastError ();
  int ret = 0;
  switch (tmperr)
    {
    case WSAEWOULDBLOCK:
      ret = EAGAIN;
      break;
    case NO_ERROR:
      ret = 0;
      break;
    case WSAEINTR:
      ret = EINTR;
      break;
    default:
      ret = EIO;
      break;
    }
  WSASetLastError (tmperr);

  return ret;
}
BOOL CControlSocket::Connect(CString hostAddress, UINT nHostPort)
{
	hostAddress = ConvertDomainName(hostAddress);

	//Don't resolve host asynchronously when using proxies
	if (m_pProxyLayer)
	{
		//If using proxies, we can't use ident -> won't be reachable from outside
		
		return CAsyncSocketEx::Connect(hostAddress, nHostPort);
	}
	BOOL res = CAsyncSocketEx::Connect(hostAddress, nHostPort);
	int nLastError = WSAGetLastError();
	if (res || nLastError==WSAEWOULDBLOCK)
	{
#ifndef MPEXT_NO_IDENT
		if (COptions::GetOptionVal(OPTION_IDENT))
			m_pIdentControl = new CIdentServerControl(this);
#endif
		WSASetLastError(nLastError);
	}
	
	return res;
}
long PCSBSocketUDP::ReadData(
				void * 				outBuf,
				long				outBufLength,
				unsigned long *		outSrcIP,
				unsigned short *	outSrcPort)
{
	SOCKADDR_IN remoteAddress;
	int fromlen = sizeof(remoteAddress);
	remoteAddress.sin_family = AF_INET;
	remoteAddress.sin_port = 0;
	remoteAddress.sin_addr.S_un.S_addr = 0;
	
	WSASetLastError(0);
	int result = recvfrom(mWinSocket, 
						 (char*)outBuf, 
						 outBufLength,
						 0,
						 (SOCKADDR*)&remoteAddress,
						 &fromlen);
		
	*outSrcIP = ntohl(remoteAddress.sin_addr.S_un.S_addr);
	*outSrcPort = ntohs(remoteAddress.sin_port);
	
	if (result == SOCKET_ERROR)
	{
		if(WSAGetLastError() != WSAEWOULDBLOCK)
		{
			return -1;
		}
	}
	else
	{
		return result;
	}
	return result;
}
//
// Creates a TCP socket for communication.  Used by server.
// "size" argument is ignored, but accepted for compatibility with PortPipe.
// (PortPipe does no longer exists, but one day there might be an successor)
//
BOOL PortTCP::Create(char *port_name, char *remote_name, DWORD size, unsigned short port_number)
{
	struct sockaddr_in sin;
	socklen_t buflen;

	network_port = port_number;	// listen at specified port (0 = system assigns port number)

	if (port_name) {
		strcpy(name, port_name);
	} else {
		// get the unqualified local host name
		if (gethostname(name, MAX_NETWORK_NAME) == SOCKET_ERROR) {
			*errmsg << "===> ERROR: Getting local host name failed." << endl
			    << "     [PortTCP::Create() in " << __FILE__ << " line " << __LINE__ << "]" << endl
			    << "     errno = " << WSAGetLastError() << ends;
			OutputErrMsg();
			return FALSE;
		}
	}

	if (remote_name) {
		strcpy(network_name, remote_name);
	} else {
		// get the specified host's first network address
		struct hostent *hostinfo = gethostbyname(name);

		if (hostinfo == NULL) {
			*errmsg << "===> ERROR: Getting host name for \"" << name << "\" failed." << endl
			    << "     [PortTCP::Create() in " << __FILE__ << " line " << __LINE__ << "]" << endl
			    << "     errno = " << WSAGetLastError() << ends;
			OutputErrMsg();
			return FALSE;
		}
		memcpy(&sin.sin_addr.s_addr, hostinfo->h_addr_list[0], hostinfo->h_length);
		strncpy(network_name, inet_ntoa(sin.sin_addr), sizeof(network_name) - 1);

	}

	//
	// Create socket.
	//

#if PORT_DETAILS || _DETAILS
	cout << "Creating socket." << endl;
	WSASetLastError(0);
#endif

	if (synchronous) {
		server_socket = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);
	}
#if defined(IOMTR_OS_WIN32) || defined(IOMTR_OS_WIN64)
	else {
		server_socket = WSASocket(AF_INET, SOCK_STREAM, PF_UNSPEC, NULL, 0, WSA_FLAG_OVERLAPPED);
	}
#endif

	if (server_socket == (int)INVALID_SOCKET) {
		*errmsg << "===> ERROR: Creating socket failed." << endl
		    << "     [PortTCP::Create() in " << __FILE__ << " line " << __LINE__ << "]" << endl
		    << "     errno = " << WSAGetLastError() << ends;
		OutputErrMsg();
		return FALSE;
	}
	//
	// Bind to socket.
	//

#if PORT_DETAILS || _DETAILS
	cout << "Binding to socket " << name << "." << endl;
	WSASetLastError(0);
#endif

	sin.sin_family = AF_INET;	// use Internet Protocol
	sin.sin_addr.s_addr = htonl(INADDR_ANY);	// listen at any available address
	sin.sin_port = htons(network_port);	// listen at specified port (0 = system assigns port number)

	if (bind(server_socket, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
		*errmsg << "===> ERROR: Binding to socket " << name << " failed." << endl
		    << "     [PortTCP::Create() in " << __FILE__ << " line " << __LINE__ << "]" << endl
		    << "     errno = " << WSAGetLastError() << ends;
		OutputErrMsg();
		return FALSE;
	}
	// get actual port number in use
	buflen = sizeof(sin);
	if (getsockname(server_socket, (struct sockaddr *)&sin, &buflen) != 0) {
		*errmsg << "===> ERROR: Getting information about server socket failed." << endl
		    << "     [PortTCP::Create() in " << __FILE__ << " line " << __LINE__ << "]" << endl
		    << "     errno = " << WSAGetLastError() << ends;
		OutputErrMsg();
		return FALSE;
	}
	network_port = ntohs(sin.sin_port);

#if PORT_DETAILS || _DETAILS
	cout << "Bound server socket on port " << network_port << "." << endl;
#endif

	return TRUE;
}
Example #12
0
void
mono_w32socket_set_last_error (gint32 error)
{
	WSASetLastError (error);
}
Example #13
0
int
create_socketpair(int family, int type, int protocol, int fd[2])
{
    /* This code is originally from Tor.  Used with permission. */

    /* This socketpair does not work when localhost is down. So
     * it's really not the same thing at all. But it's close enough
     * for now, and really, when localhost is down sometimes, we
     * have other problems too.
     */
#ifdef WIN32
#define ERR(e) WSA##e
#else
#define ERR(e) e
#endif
    int listener = -1;
    int connector = -1;
    int acceptor = -1;
    struct sockaddr_in listen_addr;
    struct sockaddr_in connect_addr;
    int size;
    int saved_errno = -1;

    if (protocol
        || (family != AF_INET
#ifdef AF_UNIX
            && family != AF_UNIX
#endif
        )) {
        opal_output(0, "Protocol not support: %d", (ERR(EAFNOSUPPORT)));
        return -1;
    }
    if (!fd) {
        opal_output(0, "Invalid socked: %d", (ERR(EINVAL)));
        return -1;
    }

    listener = socket(AF_INET, type, 0);
    if (listener < 0)
        return -1;
    memset(&listen_addr, 0, sizeof(listen_addr));
    listen_addr.sin_family = AF_INET;
    listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    listen_addr.sin_port = 0;    /* kernel chooses port.     */
    if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
        == -1)
        goto tidy_up_and_fail;
    if (listen(listener, 1) == -1)
        goto tidy_up_and_fail;

    connector = socket(AF_INET, type, 0);
    if (connector < 0)
        goto tidy_up_and_fail;
    /* We want to find out the port number to connect to.  */
    size = sizeof(connect_addr);
    if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
        goto tidy_up_and_fail;
    if (size != sizeof (connect_addr))
        goto abort_tidy_up_and_fail;
    if (connect(connector, (struct sockaddr *) &connect_addr,
                sizeof(connect_addr)) == -1)
        goto tidy_up_and_fail;

    size = sizeof(listen_addr);
    acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
    if (acceptor < 0)
        goto tidy_up_and_fail;
    if (size != sizeof(listen_addr))
        goto abort_tidy_up_and_fail;
    closesocket(listener);
    /* Now check we are talking to ourself by matching port and host on the
       two sockets.     */
    if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
        goto tidy_up_and_fail;
    if (size != sizeof (connect_addr)
        || listen_addr.sin_family != connect_addr.sin_family
        || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
        || listen_addr.sin_port != connect_addr.sin_port)
        goto abort_tidy_up_and_fail;
    fd[0] = connector;
    fd[1] = acceptor;

    return 0;

 abort_tidy_up_and_fail:
    saved_errno = ERR(ECONNABORTED);
 tidy_up_and_fail:
    if (saved_errno < 0)
        saved_errno = WSAGetLastError();
    if (listener != -1)
        closesocket(listener);
    if (connector != -1)
        closesocket(connector);
    if (acceptor != -1)
        closesocket(acceptor);

    WSASetLastError(saved_errno);
    return -1;
#undef ERR
}
Example #14
0
/*
 * Opens a TCP/IP connection to the remote server on the given host.
 * The address of the remote host will be returned in hostaddr.
 * If port is 0, the default port will be used.  If needpriv is true,
 * a privileged port will be allocated to make the connection.
 * This requires super-user privileges if needpriv is true.
 * Connection_attempts specifies the maximum number of tries (one per
 * second).  If proxy_command is non-NULL, it specifies the command (with %h
 * and %p substituted for host and port, respectively) to use to contact
 * the daemon.
 */
static int
ssh_connect_direct(const char *host, struct addrinfo *aitop,
    struct sockaddr_storage *hostaddr, u_short port, int family,
    int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)
{
	int on = 1;
	int sock = -1, attempt;
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
	struct addrinfo *ai;

  #ifdef WIN32_FIXME

  DWORD error_win32 = 0;

  #endif
	debug2("ssh_connect: needpriv %d", needpriv);

	for (attempt = 0; attempt < connection_attempts; attempt++) {
		if (attempt > 0) {
			/* Sleep a moment before retrying. */
			sleep(1);
			debug("Trying again...");
		}
		/*
		 * Loop through addresses for this host, and try each one in
		 * sequence until the connection succeeds.
		 */
		for (ai = aitop; ai; ai = ai->ai_next) {
			if (ai->ai_family != AF_INET &&
			    ai->ai_family != AF_INET6)
				continue;
			if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
			    ntop, sizeof(ntop), strport, sizeof(strport),
			    NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
				error("ssh_connect: getnameinfo failed");
				continue;
			}
			debug("Connecting to %.200s [%.100s] port %s.",
				host, ntop, strport);

			/* Create a socket for connecting. */
			sock = ssh_create_socket(needpriv, ai);
			if (sock < 0)
				/* Any error is already output */
				continue;

			if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
			    timeout_ms) >= 0) {
				/* Successful connection. */
				memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
				break;
			} else {
				debug("connect to address %s port %s: %s",
				    ntop, strport, strerror(errno));
#ifdef WIN32_FIXME
                                error_win32 = WSAGetLastError();
#endif
				close(sock);
				sock = -1;
			}
		}
		if (sock != -1)
			break;	/* Successful connection. */
	}

	/* Return failure if we didn't get a successful connection. */
	if (sock == -1) {
#ifdef WIN32_FIXME
                WSASetLastError(error_win32);
#endif
		error("ssh: connect to host %s port %s: %s",
		    host, strport, strerror(errno));
		return (-1);
	}

	debug("Connection established.");

	/* Set SO_KEEPALIVE if requested. */
	if (want_keepalive &&
	    setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
	    sizeof(on)) < 0)
		error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));

	/* Set the connection. */
	packet_set_connection(sock, sock);

	return 0;
}
Example #15
0
BOOL CSocket::PumpMessages(UINT uStopFlag)
{
	// The same socket better not be blocking in more than one place.
	ASSERT(m_pbBlocking == NULL);

	AFX_THREAD_STATE* pThreadState = AfxGetThreadState();

	ASSERT(pThreadState->m_hSocketWindow != NULL);

	BOOL bBlocking = TRUE;
	m_pbBlocking = &bBlocking;
	CWinThread* pThread = AfxGetThread();

	UINT nTimerID = ::SetTimer(NULL, 0xff00, m_nTimeOut, NULL);

	if (nTimerID == 0)
		AfxThrowResourceException();

	while (bBlocking)
	{
		TRY
		{
			MSG msg;
			if (::PeekMessage(&msg, pThreadState->m_hSocketWindow,
				WM_SOCKET_NOTIFY, WM_SOCKET_DEAD, PM_REMOVE))
			{
				if (msg.message == WM_SOCKET_NOTIFY && (SOCKET)msg.wParam == m_hSocket)
				{
					if (WSAGETSELECTEVENT(msg.lParam) == FD_CLOSE)
					{
						break;
					}
					if (WSAGETSELECTEVENT(msg.lParam) == uStopFlag)
					{
						if (uStopFlag == FD_CONNECT)
							m_nConnectError = WSAGETSELECTERROR(msg.lParam);
						break;
					}
				}
				if (msg.wParam != 0 || msg.lParam != 0)
					CSocket::AuxQueueAdd(msg.message, msg.wParam, msg.lParam);
			}
			else if (::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_NOREMOVE))
			{
				if (msg.wParam == nTimerID)
				{
					::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE);
					break;
				}
			}
			else if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) &&
				OnMessagePending())
			{
				// allow user-interface updates
				pThread->OnIdle(-1);
			}
			else
			{
				// no work to do -- allow CPU to sleep
				WaitMessage();
			}
		}
		CATCH_ALL(e)
		{
			TRACE0("Error: caught exception in PumpMessage - continuing.\n");
			DELETE_EXCEPTION(e);
		}
		END_CATCH_ALL
	}

	::KillTimer(NULL, nTimerID);

	if (!bBlocking)
	{
		WSASetLastError(WSAEINTR);
		return FALSE;
	}
	m_pbBlocking = NULL;

	::PostMessage(pThreadState->m_hSocketWindow,WM_SOCKET_NOTIFY,0,0);

 	return TRUE;
}
/**
 * Emit a log message. This function is the variable argument list equivalent
 * to vlc_Log().
 */
void vlc_vaLog (vlc_object_t *obj, int type, const char *module,
                const char *format, va_list args)
{
    if (obj != NULL && obj->i_flags & OBJECT_FLAGS_QUIET)
        return;

    /* C locale to get error messages in English in the logs */
    locale_t c = newlocale (LC_MESSAGES_MASK, "C", (locale_t)0);
    locale_t locale = uselocale (c);

#ifndef __GLIBC__
    /* Expand %m to strerror(errno) - only once */
    char buf[strlen(format) + 2001], *ptr;
    strcpy (buf, format);
    ptr = (char*)buf;
    format = (const char*) buf;

    for( ;; )
    {
        ptr = strchr( ptr, '%' );
        if( ptr == NULL )
            break;

        if( ptr[1] == 'm' )
        {
            char errbuf[2001];
            size_t errlen;

#ifndef WIN32
            strerror_r( errno, errbuf, 1001 );
#else
            int sockerr = WSAGetLastError( );
            if( sockerr )
            {
                strncpy( errbuf, net_strerror( sockerr ), 1001 );
                WSASetLastError( sockerr );
            }
            if ((sockerr == 0)
             || (strcmp ("Unknown network stack error", errbuf) == 0))
                strncpy( errbuf, strerror( errno ), 1001 );
#endif
            errbuf[1000] = 0;

            /* Escape '%' from the error string */
            for( char *percent = strchr( errbuf, '%' );
                 percent != NULL;
                 percent = strchr( percent + 2, '%' ) )
            {
                memmove( percent + 1, percent, strlen( percent ) + 1 );
            }

            errlen = strlen( errbuf );
            memmove( ptr + errlen, ptr + 2, strlen( ptr + 2 ) + 1 );
            memcpy( ptr, errbuf, errlen );
            break; /* Only once, so we don't overflow */
        }

        /* Looks for conversion specifier... */
        do
            ptr++;
        while( *ptr && ( strchr( "diouxXeEfFgGaAcspn%", *ptr ) == NULL ) );
        if( *ptr )
            ptr++; /* ...and skip it */
    }
#endif

    /* Fill message information fields */
    msg_item_t msg;

    msg.i_object_id = (uintptr_t)obj;
    msg.psz_object_type = (obj != NULL) ? obj->psz_object_type : "generic";
    msg.psz_module = module;
    msg.psz_header = NULL;

    for (vlc_object_t *o = obj; o != NULL; o = o->p_parent)
        if (o->psz_header != NULL)
        {
            msg.psz_header = o->psz_header;
            break;
        }

    /* Pass message to subscribers */
    libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc);

    va_list ap;

    va_copy (ap, args);
    if (priv->b_color)
        PrintColorMsg (&priv->i_verbose, type, &msg, format, ap);
    else
        PrintMsg (&priv->i_verbose, type, &msg, format, ap);
    va_end (ap);

    vlc_rwlock_rdlock (&msg_lock);
    for (msg_subscription_t *sub = msg_head; sub != NULL; sub = sub->next)
    {
        va_copy (ap, args);
        sub->func (sub->opaque, type, &msg, format, ap);
        va_end (ap);
    }
    vlc_rwlock_unlock (&msg_lock);

    uselocale (locale);
    freelocale (c);
}
Example #17
0
    /** sends all data or throws an exception
     * @param context descriptive for logging
     */
    void Socket::send( const vector< pair< char *, int > > &data, const char *context ) {

#ifdef MONGO_CONFIG_SSL
        if ( _sslConnection.get() ) {
            _send( data , context );
            return;
        }
#endif

#if defined(_WIN32)
        // TODO use scatter/gather api
        _send( data , context );
#else
        vector<struct iovec> d( data.size() );
        int i = 0;
        for (vector< pair<char *, int> >::const_iterator j = data.begin(); 
             j != data.end(); 
             ++j) {
            if ( j->second > 0 ) {
                d[ i ].iov_base = j->first;
                d[ i ].iov_len = j->second;
                ++i;
                _bytesOut += j->second;
            }
        }
        struct msghdr meta;
        memset( &meta, 0, sizeof( meta ) );
        meta.msg_iov = &d[ 0 ];
        meta.msg_iovlen = d.size();

        while( meta.msg_iovlen > 0 ) {
            int ret = -1;
            if (MONGO_FAIL_POINT(throwSockExcep)) {
#if defined(_WIN32)
                WSASetLastError(WSAENETUNREACH);
#else
                errno = ENETUNREACH;
#endif
            }
            else {
                ret = ::sendmsg(_fd, &meta, portSendFlags);
            }

            if (ret == -1) {
                if ( errno != EAGAIN || _timeout == 0 ) {
                    LOG(_logLevel) << "Socket " << context << 
                        " send() " << errnoWithDescription() << ' ' << remoteString() << endl;
                    throw SocketException( SocketException::SEND_ERROR , remoteString() );
                }
                else {
                    LOG(_logLevel) << "Socket " << context << 
                        " send() remote timeout " << remoteString() << endl;
                    throw SocketException( SocketException::SEND_TIMEOUT , remoteString() );
                }
            }
            else {
                struct iovec *& i = meta.msg_iov;
                while( ret > 0 ) {
                    if ( i->iov_len > unsigned( ret ) ) {
                        i->iov_len -= ret;
                        i->iov_base = (char*)(i->iov_base) + ret;
                        ret = 0;
                    }
                    else {
                        ret -= i->iov_len;
                        ++i;
                        --(meta.msg_iovlen);
                    }
                }
            }
        }
#endif
    }
Example #18
0
/*----------------------------------------------------------------------*
                         rtp_net_setmembership
 *----------------------------------------------------------------------*/
int rtp_net_setmembership (RTP_HANDLE sockHandle, unsigned char * ipAddr, int type, unsigned int onBool)
{
#ifdef LINUXTOBEIMPLEMENTED
    struct sockaddr_in localAddr;
    int result;
    int localLen;
    struct ip_mreq mcreq;
    unsigned long in_addr = 0;
    
    localLen = sizeof(localAddr);
    memset(&localAddr, 0, localLen);
    memset( ( void * )&mcreq, 0, sizeof( struct ip_mreq ) );
    
    if (ipAddr)
    {
        unsigned char *ptr = (unsigned char *) &in_addr;
        
        if (type == RTP_NET_TYPE_IPV4)
        {
            ptr[0] = ipAddr[0];
            ptr[1] = ipAddr[1];
            ptr[2] = ipAddr[2];
            ptr[3] = ipAddr[3];
        }
        else
        {
            /* ----------------------------------- */
            /* RTP_NET_TYPE_IPV6 not yet supported */
            /* ----------------------------------- */
            return (-1);
        }
    }
    else
    {
        in_addr = INADDR_ANY;
    }

#ifdef RTP_DEBUG
    /* ----------------------------------- */
    /*  Clear the error state by setting   */
    /*  to 0.                              */
    /* ----------------------------------- */
    WSASetLastError (0);
#endif

    if (getsockname ((SOCKET) sockHandle, (struct sockaddr *) &localAddr, (int *) &localLen) != 0)
    {
#ifdef RTP_DEBUG
        result = WSAGetLastError();
        RTP_DEBUG_OUTPUT_STR("rtp_net_setmembership: error returned ");
        RTP_DEBUG_OUTPUT_INT(result);
        RTP_DEBUG_OUTPUT_STR(".\n");
#endif
        return (-1);
    }
    
    memmove(&mcreq.imr_multiaddr.s_addr, &in_addr, 4);
    memmove(&mcreq.imr_interface.s_addr, &localAddr.sin_addr.s_addr, 4); 

    if (onBool)
    {
        result = setsockopt((int) sockHandle, IPPROTO_IP, 
                            IP_ADD_MEMBERSHIP, (const char *)&mcreq, 
                            sizeof( struct ip_mreq ));
    }
    else
    {
        result = setsockopt((int) sockHandle, IPPROTO_IP, 
                            IP_DROP_MEMBERSHIP, (const char *)&mcreq, 
                            sizeof( struct ip_mreq ));
    }
        
    if (result != 0)
    {
#ifdef RTP_DEBUG
        result = WSAGetLastError();
        RTP_DEBUG_OUTPUT_STR("rtp_net_setmembership: error returned ");
        RTP_DEBUG_OUTPUT_INT(result);
        RTP_DEBUG_OUTPUT_STR(".\n");
#endif
        return (-1);
    }
    return (0);
#else
	return (0);
#endif
}
Example #19
0
/*
 * '_sspiWrite()' - Write a buffer to an ssl socket
 */
int					/* O  - Bytes written or SOCKET_ERROR */
_sspiWrite(_sspi_struct_t *conn,	/* I  - Client connection */
           void           *buf,		/* I  - Buffer */
           size_t         len)		/* I  - Buffer length */
{
  SecBufferDesc	message;		/* Array of SecBuffer struct */
  SecBuffer	buffers[4] = { 0 };	/* Security package buffer */
  BYTE		*buffer = NULL;		/* Scratch buffer */
  int		bufferLen;		/* Buffer length */
  size_t	bytesLeft;		/* Bytes left to write */
  int		index = 0;		/* Index into buffer */
  int		num = 0;		/* Return value */

  if (!conn || !buf || !len)
  {
    WSASetLastError(WSAEINVAL);
    num = SOCKET_ERROR;
    goto cleanup;
  }

  bufferLen = conn->streamSizes.cbMaximumMessage +
              conn->streamSizes.cbHeader +
              conn->streamSizes.cbTrailer;

  buffer = (BYTE*) malloc(bufferLen);

  if (!buffer)
  {
    DEBUG_printf(("_sspiWrite: buffer alloc of %d bytes failed", bufferLen));
    WSASetLastError(E_OUTOFMEMORY);
    num = SOCKET_ERROR;
    goto cleanup;
  }

  bytesLeft = len;

  while (bytesLeft)
  {
    size_t chunk = min(conn->streamSizes.cbMaximumMessage,	/* Size of data to write */
                       bytesLeft);
    SECURITY_STATUS scRet;					/* SSPI status */

   /*
    * Copy user data into the buffer, starting
    * just past the header
    */
    memcpy(buffer + conn->streamSizes.cbHeader,
           ((BYTE*) buf) + index,
           chunk);

   /*
    * Setup the SSPI buffers
    */
    message.ulVersion = SECBUFFER_VERSION;
    message.cBuffers = 4;
    message.pBuffers = buffers;
    buffers[0].pvBuffer = buffer;
    buffers[0].cbBuffer = conn->streamSizes.cbHeader;
    buffers[0].BufferType = SECBUFFER_STREAM_HEADER;
    buffers[1].pvBuffer = buffer + conn->streamSizes.cbHeader;
    buffers[1].cbBuffer = (unsigned long) chunk;
    buffers[1].BufferType = SECBUFFER_DATA;
    buffers[2].pvBuffer = buffer + conn->streamSizes.cbHeader + chunk;
    buffers[2].cbBuffer = conn->streamSizes.cbTrailer;
    buffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
    buffers[3].BufferType = SECBUFFER_EMPTY;

   /*
    * Encrypt the data
    */
    scRet = EncryptMessage(&conn->context, 0, &message, 0);

    if (FAILED(scRet))
    {
      DEBUG_printf(("_sspiWrite: EncryptMessage failed: %x", scRet));
      WSASetLastError(WSASYSCALLFAILURE);
      num = SOCKET_ERROR;
      goto cleanup;
    }

   /*
    * Send the data. Remember the size of
    * the total data to send is the size
    * of the header, the size of the data
    * the caller passed in and the size
    * of the trailer
    */
    num = send(conn->sock,
               buffer,
               buffers[0].cbBuffer + buffers[1].cbBuffer + buffers[2].cbBuffer,
               0);

    if ((num == SOCKET_ERROR) || (num == 0))
    {
      DEBUG_printf(("_sspiWrite: send failed: %ld", WSAGetLastError()));
      goto cleanup;
    }

    bytesLeft -= (int) chunk;
    index += (int) chunk;
  }

  num = (int) len;

cleanup:

  if (buffer)
    free(buffer);

  return (num);
}
Example #20
0
int socketpair(int domain, int type, int protocol, SOCKET socks[2])
{
    int make_overlapped = 1;
    union {
        struct sockaddr_in inaddr;
        struct sockaddr addr;
    } a;

    SOCKET listener;
    int e;
    socklen_t addrlen = sizeof(a.inaddr);
    DWORD flags = (make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
    int reuse = 1;

    if (socks == 0) {
        WSASetLastError(WSAEINVAL);
        return SOCKET_ERROR;
    }

    listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    int i = WSAGetLastError();
    if (listener == INVALID_SOCKET)
        return SOCKET_ERROR;

    memset(&a, 0, sizeof(a));
    a.inaddr.sin_family = AF_INET;
    a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    a.inaddr.sin_port = 0;

    socks[0] = socks[1] = INVALID_SOCKET;
    do {
        if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
            (char*)&reuse, (socklen_t) sizeof(reuse)) == -1)
            break;
        if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
            break;

        memset(&a, 0, sizeof(a));
        if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR)
            break;
        // win32 getsockname may only set the port number, p=0.0005.
        // ( http://msdn.microsoft.com/library/ms738543.aspx ):
        a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
        a.inaddr.sin_family = AF_INET;

        if (listen(listener, 1) == SOCKET_ERROR)
            break;

        socks[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, flags);
        if (socks[0] == INVALID_SOCKET)
            break;
        if (connect(socks[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
            break;

        socks[1] = accept(listener, NULL, NULL);
        if (socks[1] == INVALID_SOCKET)
            break;

        closesocket(listener);
        return 0;

    } while (0);

    e = WSAGetLastError();
    closesocket(listener);
    closesocket(socks[0]);
    closesocket(socks[1]);
    WSASetLastError(e);
    return SOCKET_ERROR;
}
Example #21
0
int socketpair(int domain, int type, int protocol, int socket_vector[2])
{
	if (domain != AF_UNIX || !(type & SOCK_STREAM) || protocol != PF_UNSPEC)
		return -1;

	socket_vector[0] = -1;
	socket_vector[1] = -1;

	int listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (listener == -1) {
		return -1;
	}

	struct sockaddr_in addr = {
		.sin_family = AF_INET,
		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
		.sin_port = 0,
	};

	int yes = 1, e;
	if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
			(void *)&yes, sizeof yes) == -1)
		goto err;

	if (bind(listener, (struct sockaddr *)&addr, sizeof addr) != 0)
		goto err;

	memset(&addr, 0, sizeof addr);
	socklen_t addrlen = sizeof addr;
	if (getsockname(listener, (struct sockaddr *)&addr, &addrlen) != 0)
		goto err;

	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	addr.sin_family = AF_INET;

	if (listen(listener, 1) != 0)
		goto err;

	socket_vector[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
	if (socket_vector[0] == -1)
		goto err;

	if (connect(socket_vector[0], (struct sockaddr *)&addr, sizeof addr) != 0)
		goto err;

	socket_vector[1] = accept(listener, NULL, NULL);
	if (socket_vector[1] == -1)
		goto err;

	closesocket(listener);
	return 0;

err:
	e = WSAGetLastError();
	closesocket(listener);
	closesocket(socket_vector[0]);
	closesocket(socket_vector[1]);
	WSASetLastError(e);
	socket_vector[0] = -1;
	socket_vector[1] = -1;
	return -1;
}

int pipe(int fildes[2])
{
	return socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC, fildes);
}

#else

static int setfd(int fd, int flag)
{
	int flags = fcntl(fd, F_GETFD);
	flags |= flag;
	return fcntl(fd, F_SETFD, flags);
}
Example #22
0
/**
 *  versucht eine Verbindung mit einem externen Host aufzubauen.
 *
 *  @param[in] hostname Ziel-Hostname/-ip
 *  @param[in] port     Port zu dem Verbunden werden soll
 *
 *  @p true bei Erfolg, @p false bei Fehler
 *
 *  @author FloSoft
 */
bool Socket::Connect(const std::string& hostname, const unsigned short port, bool use_ipv6, const Socket::PROXY_TYPE typ, const std::string& proxy_hostname, const unsigned int proxy_port)
{
    if(typ == PROXY_SOCKS4)
        use_ipv6 = false;

    std::vector<HostAddr> proxy_ips;
    if(typ != PROXY_NONE)
    {
        proxy_ips = HostToIp(proxy_hostname, proxy_port, use_ipv6);
        if(proxy_ips.size() == 0)
            return false;
    }

    // TODO: socks v5 kann remote resolven
    std::vector<HostAddr> ips = HostToIp(hostname, port, use_ipv6);
    if(ips.size() == 0)
        return false;

    bool done = false;

    std::vector<HostAddr>::const_iterator start, end;

    // do not use proxy for connecting to localhost
    if(typ != PROXY_NONE && hostname != "localhost")
    {
        start = proxy_ips.begin();
        end = proxy_ips.end();
    }
    else
    {
        start = ips.begin();
        end = ips.end();
    }

    for(std::vector<HostAddr>::const_iterator it = start; it != end; ++it)
    {
        if(it->isUDP)
            throw std::invalid_argument("Cannot connect to UDP (yet)");

        if(!Create(it->ipv6 ? AF_INET6 : AF_INET))
            continue;

        // aktiviere non-blocking
        unsigned long argp = 1;
#ifdef _WIN32
        ioctlsocket(socket_, FIONBIO, &argp);
#else
        ioctl(socket_, FIONBIO, &argp);
#endif

        ResolvedAddr addr(*it);
        std::string ip = IpToString(addr.getAddr().ai_addr); //-V807
        LOG.lprintf("Verbinde mit %s%s:%d\n", (typ != PROXY_NONE ? "Proxy " : ""), ip.c_str(), (typ != PROXY_NONE ? proxy_port : port));

        // Und schließlich Verbinden
        if(connect(socket_, addr.getAddr().ai_addr, addr.getAddr().ai_addrlen) != SOCKET_ERROR)
        {
            done = true;
            break;
        }
#ifdef _WIN32
        if(WSAGetLastError() == WSAEWOULDBLOCK)
#else
        if(errno == EINPROGRESS || errno == EWOULDBLOCK)
#endif
        {
            int timeout = 0;
            while(!done)
            {
                SocketSet sw, se;
                sw.Add(*this);
                se.Add(*this);

                if(sw.Select(0, 1) == 1 || se.Select(0, 2) != 0)
                {
                    unsigned int err;
                    socklen_t len = sizeof(unsigned int);
                    getsockopt(socket_, SOL_SOCKET, SO_ERROR, (char*)&err, &len);

                    if(err != 0)
                    {
#ifdef _WIN32
                        WSASetLastError(err);
#else
                        errno = err;
#endif
                        break;
                    }

                    switch(typ)
                    {
                        default:
                            break;
                        case PROXY_SOCKS4:
                        {
                            union{
                                char proxyinit[18];
                                unsigned short proxyInitShort[9];
                            };

                            proxyinit[0] = 4; // socks v4
                            proxyinit[1] = 1; // 1=connect
                            proxyInitShort[1] = htons(port);
                            for(std::vector<HostAddr>::const_iterator it = ips.begin(); it != ips.end(); ++it)
                            {
                                if(!it->ipv6)
                                    sscanf(it->host.c_str(), "%c.%c.%c.%c", &proxyinit[4], &proxyinit[5], &proxyinit[6], &proxyinit[7]);
                            }
                            strcpy(&proxyinit[8], "siedler25"); // userid

                            Send(proxyinit, 18);

                            int proxy_timeout = 0;
                            while(BytesWaiting() < 8 && proxy_timeout < 8)
                            {
                                Sleep(250);
                                ++proxy_timeout;
                            }

                            if(proxy_timeout >= 8)
                            {
                                LOG.lprintf("Proxy error: connection timed out\n");
                                return false;
                            }

                            Recv(proxyinit, 8);

                            if(proxyinit[0] != 0 || proxyinit[1] != 90)
                            {
                                LOG.lprintf("Proxy error: got %d: connection rejected or failed or other error\n", proxyinit[1]);
                                return false;
                            }
                        } break;
                        case PROXY_SOCKS5:
                        {
                            // not implemented
                            return false;
                        } break;
                    }

                    // Verbindung hergestellt
                    done = true;
                }

                Sleep(50);

                ++timeout;
                if(timeout > 8)
                {
#ifdef _WIN32
                    WSASetLastError(WSAETIMEDOUT);
#else
                    errno = ETIMEDOUT;
#endif
                    break;
                }
            }
            if(done)
                break;
        }
        LOG.getlasterror("Verbindung fehlgeschlagen\nFehler");
    }

    if(!done)
    {
        LOG.lprintf("Fehler beim Verbinden mit %s:%d\n", hostname.c_str(), port);
        return false;
    }
    LOG.lprintf("Verbindung erfolgreich hergestellt mit %s:%d\n", hostname.c_str(), port);

    // deaktiviere non-blocking
    unsigned long argp = 0;
#ifdef _WIN32
    ioctlsocket(socket_, FIONBIO, &argp);
#else
    ioctl(socket_, FIONBIO, &argp);
#endif

    status_ = CONNECT;

    // Alles ok
    return true;
}
Example #23
0
/*
 * Curl_wait_for_resolv() waits for a resolve to finish. This function should
 * be avoided since using this risk getting the multi interface to "hang".
 *
 * If 'entry' is non-NULL, make it point to the resolved dns entry
 *
 * This is the version for resolves-in-a-thread.
 */
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
                              struct Curl_dns_entry **entry)
{
  struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
  struct SessionHandle *data = conn->data;
  long   timeout;
  DWORD  status, ticks;
  CURLcode rc;

  curlassert (conn && td);

  /* now, see if there's a connect timeout or a regular timeout to
     use instead of the default one */
  timeout =
    conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
    conn->data->set.timeout ? conn->data->set.timeout :
    CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
  ticks = GetTickCount();
  (void)ticks;

  status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout);
  if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) {
     /* Thread finished before timeout; propagate Winsock error to this thread.
      * 'conn->async.done = TRUE' is set in Curl_addrinfo4/6_callback().
      */
     WSASetLastError(conn->async.status);
     GetExitCodeThread(td->thread_hnd, &td->thread_status);
     TRACE(("%s() status %lu, thread retval %lu, ",
            THREAD_NAME, status, td->thread_status));
  }
  else {
     conn->async.done = TRUE;
     td->thread_status = (DWORD)-1;
     TRACE(("%s() timeout, ", THREAD_NAME));
  }

  TRACE(("elapsed %lu ms\n", GetTickCount()-ticks));

  CloseHandle(td->thread_hnd);

  if(entry)
    *entry = conn->async.dns;

  rc = CURLE_OK;

  if (!conn->async.dns) {
    /* a name was not resolved */
    if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
      failf(data, "Resolving host timed out: %s", conn->host.name);
      rc = CURLE_OPERATION_TIMEDOUT;
    }
    else if(conn->async.done) {
      failf(data, "Could not resolve host: %s; %s",
            conn->host.name, Curl_strerror(conn,conn->async.status));
      rc = CURLE_COULDNT_RESOLVE_HOST;
    }
    else
      rc = CURLE_OPERATION_TIMEDOUT;
  }

  destroy_thread_data(&conn->async);

  if(CURLE_OK != rc)
    /* close the connection, since we must not return failure from here
       without cleaning up this connection properly */
    Curl_disconnect(conn);

  return (rc);
}
//
// Connects to an existing port waiting to accept a connection.  Used by client.
//     port_name is a hostname or a string IP address ("xxx.xxx.xxx.xxx").
//     port_number is the port number to use at that address.
//
BOOL PortTCP::Connect(char *port_name, unsigned short port_number)
{
	unsigned long server_address = INADDR_NONE;
	struct sockaddr_in sin;
	struct hostent *hostinfo;
	int retval;

	// get hostname to connect to (default local host name).

	if (strlen(port_name)) {
		strcpy(name, port_name);
	} else {
		if (gethostname(name, MAX_NETWORK_NAME) == SOCKET_ERROR) {
			*errmsg << "===> ERROR: Getting local host name failed." << endl
			    << "     [PortTCP::Connect() in " << __FILE__ << " line " << __LINE__ << "]" << endl
			    << "     errno = " << WSAGetLastError() << ends;
			OutputErrMsg();
			return FALSE;
		}
	}

	if (atoi(name) > 0) {
		// looks like a numeric IP address was specified
		// if this is not an IP address (e.g., a name starting with a digit),
		//      INADDR_NONE (0xffffffff) will be returned.
		server_address = inet_addr(name);
	}

	if (server_address == INADDR_NONE) {
		// treat it as a hostname
		hostinfo = gethostbyname(name);
		if (hostinfo == NULL) {
			*errmsg << "===> ERROR: Getting host information for \"" << name << "\" failed." << endl
			    << "     [PortTCP::Connect() in " << __FILE__ << " line " << __LINE__ << "]" << endl
			    << "     errno = " << WSAGetLastError() << ends;
			OutputErrMsg();
			return FALSE;
		}

		memcpy(&server_address, hostinfo->h_addr, hostinfo->h_length);
	}
	// create socket for the connnection.

#if PORT_DETAILS || _DETAILS
	cout << "Creating socket " << name << "." << endl;
	WSASetLastError(0);
#endif

	if (synchronous) {
		client_socket = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);
	}
#if defined(IOMTR_OS_WIN32) || defined(IOMTR_OS_WIN64)
	else {
		client_socket = WSASocket(AF_INET, SOCK_STREAM, PF_UNSPEC, NULL, 0, WSA_FLAG_OVERLAPPED);
	}
#endif

	if (client_socket == (int)INVALID_SOCKET) {
		*errmsg << "===> ERROR: Creating socket failed." << endl
		    << "     [PortTCP::Connect() in " << __FILE__ << " line " << __LINE__ << "]" << endl
		    << "     errno = " << WSAGetLastError() << ends;
		OutputErrMsg();
		return FALSE;
	}
	// specify protocol, port, and address to connect to.

	sin.sin_family = AF_INET;	// use Internet Protocol
	sin.sin_port = htons(port_number);	// connect to this port
	sin.sin_addr.s_addr = server_address;	// connect to this server

#if PORT_DETAILS || _DETAILS
	cout << "Host address: " << inet_ntoa(sin.sin_addr) << endl;
#endif

	// attempt to connect (keep trying forever if necessary).

	do {
#if PORT_DETAILS || _DETAILS
		cout << "Attempting to connect to socket " << name << "." << endl;
		WSASetLastError(0);
#endif

		retval = connect(client_socket, (struct sockaddr *)&sin, sizeof(sin));

		if (retval != 0) {
#if PORT_DETAILS || _DETAILS
			// WSAECONNREFUSED means the server isn't up yet or is busy,
			// don't print an error message
#if defined(IOMTR_OSFAMILY_NETWARE) || defined(IOMTR_OSFAMILY_UNIX)
			if (errno != ECONNREFUSED)
#elif defined(IOMTR_OSFAMILY_WINDOWS)
			if (WSAGetLastError() != WSAECONNREFUSED)
#else
#warning ===> WARNING: You have to do some coding here to get the port done!
#endif
			{
				*errmsg << "===> ERROR: Connecting to socket " << name << " failed." << endl
				    << "     [PortTCP::Connect() in " << __FILE__ << " line " << __LINE__ << "]" << endl
				    << "     errno = " << WSAGetLastError() << ends;
				OutputErrMsg();
			}
#endif
#if defined(IOMTR_OSFAMILY_NETWARE) || defined(IOMTR_OSFAMILY_UNIX)
			// According to connect(3XN):
			//      If connect() fails, the state of the socket
			//      is  unspecified.  Portable  applications
			//      should close the file descriptor and
			//      create a new socket before attempting to
			//      reconnect.

#if PORT_DETAILS || _DETAILS
			cout << "Re-creating socket " << name << "." << endl;
			WSASetLastError(0);
#endif

			if (close(client_socket) < 0) {
				*errmsg << "===> ERROR: Closing socket " << name << " failed." << endl
				    << "     [PortTCP::Connect() in " << __FILE__ << " line " << __LINE__ << "]" << endl
				    << "     errno = " << WSAGetLastError() << ends;
				OutputErrMsg();
				return FALSE;
			}

			if ((client_socket = socket(AF_INET, SOCK_STREAM, PF_UNSPEC))
			    == (int)INVALID_SOCKET) {
				*errmsg << "===> ERROR: Recreating socket " << name << " failed." << endl
				    << "     [PortTCP::Connect() in " << __FILE__ << " line " << __LINE__ << "]" << endl
				    << "     errno = " << WSAGetLastError() << ends;
				OutputErrMsg();
				return FALSE;
			}
#endif				// IOMTR_OSFAMILY_UNIX
			Sleep(RETRY_DELAY);
		}
	}
	while (retval != 0);

	printf("Successful PortTCP::Connect\n  - port name: %s\n", name);

	return TRUE;
}
//
// Begin accepting a connection to an existing port.  Used by server.
// For synchronous port, blocks until a connection is made (returns TRUE) or an error occurs (returns FALSE).
// For asynchronous port, returns immediately.  Returns TRUE for success or FALSE if any error occurs.
//     Call IsAcceptComplete() to determine if it has completed, and GetAcceptResult() to get result.
//
BOOL PortTCP::Accept()
{
	//
	// Listen to socket.
	//

#if PORT_DETAILS || _DETAILS
	cout << "Listening to socket " << name << "." << endl;
	WSASetLastError(0);
#endif

	if (listen(server_socket, 0) != 0)	// allow at most one connection at a time
	{
		*errmsg << "===> ERROR: Listening to socket " << name << " failed." << endl
		    << "     [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << endl
		    << "     errno = " << WSAGetLastError() << ends;
		OutputErrMsg();
		return FALSE;
	}
	//
	// Accept connections to socket.
	//

#if PORT_DETAILS || _DETAILS
	cout << "Accepting connections to socket " << name << "." << endl;
	WSASetLastError(0);
#endif

	if (synchronous) {
		// don't need any info about who we're talking to
		client_socket = accept(server_socket, NULL, NULL);

		if (client_socket == (int)INVALID_SOCKET) {
			*errmsg << "===> ERROR: Accepting connection to socket " << name << " failed." << endl
			    << "     [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << endl
			    << "     errno = " << WSAGetLastError() << ends;
			OutputErrMsg();
			return FALSE;
		} else {
			return TRUE;
		}
	}
#if defined(IOMTR_OS_WIN32) || defined(IOMTR_OS_WIN64)
	else {
		DWORD bytes_received;

		if (!InitOverlapped(&accept_overlapped)) {
			*errmsg << "===> ERROR: Creating OVERLAPPED structure for socket " << name << " failed." << endl
			    << "     [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << ends;
			OutputErrMsg();
			return FALSE;
		}

		//
		// Create client socket.
		//

#if PORT_DETAILS || _DETAILS
		cout << "Creating client socket for " << name << "." << endl;
		WSASetLastError(0);
#endif

		client_socket = WSASocket(AF_INET, SOCK_STREAM, PF_UNSPEC, NULL, 0, WSA_FLAG_OVERLAPPED);

		if (client_socket == INVALID_SOCKET) {
			*errmsg << "===> ERROR: Creating client socket for " << name << " failed." << endl
			    << "     [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << endl
			    << "     errno = " << WSAGetLastError() << ends;
			OutputErrMsg();
			return FALSE;
		}
		//
		// Accept connections to socket.
		//
		if (AcceptEx(server_socket, client_socket, accept_ex_buffer, 0,	// read no data, only the two addresses, into accept_ex_buffer
			     sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
			     &bytes_received, &accept_overlapped)) {
#if PORT_DETAILS || _DETAILS
			cout << "Connection accepted." << endl;
#endif

			return TRUE;
		} else {
			if (WSAGetLastError() == WSA_IO_PENDING)	// Read started OK...
			{
				return TRUE;
			} else {
				*errmsg << "===> ERROR: AcceptEx() failed." << endl
				    << "     [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << ends;
				OutputErrMsg();
				return FALSE;
			}
		}
	}
#elif defined(IOMTR_OS_LINUX) || defined(IOMTR_OS_NETWARE) || defined(IOMTR_OS_OSX) || defined(IOMTR_OS_SOLARIS)
	else {
Example #26
0
/*
 * '_sspiRead()' - Read a buffer from an ssl socket
 */
int					/* O  - Bytes read or SOCKET_ERROR */
_sspiRead(_sspi_struct_t *conn,		/* I  - Client connection */
          void           *buf,		/* I  - Buffer */
          size_t         len)		/* I  - Buffer length */
{
  SecBufferDesc	message;		/* Array of SecBuffer struct */
  SecBuffer	buffers[4] = { 0 };	/* Security package buffer */
  int		num = 0;		/* Return value */

  if (!conn)
  {
    WSASetLastError(WSAEINVAL);
    num = SOCKET_ERROR;
    goto cleanup;
  }

 /*
  * If there are bytes that have already been
  * decrypted and have not yet been read, return
  * those
  */
  if (buf && (conn->readBufferUsed > 0))
  {
    int bytesToCopy = (int) min(conn->readBufferUsed, len);	/* Amount of bytes to copy */
								/* from read buffer */

    memcpy(buf, conn->readBuffer, bytesToCopy);
    conn->readBufferUsed -= bytesToCopy;

    if (conn->readBufferUsed > 0)
     /*
      * If the caller didn't request all the bytes
      * we have in the buffer, then move the unread
      * bytes down
      */
      memmove(conn->readBuffer,
              conn->readBuffer + bytesToCopy,
              conn->readBufferUsed);

    num = bytesToCopy;
  }
  else
  {
    PSecBuffer		pDataBuffer;	/* Data buffer */
    PSecBuffer		pExtraBuffer;	/* Excess data buffer */
    SECURITY_STATUS	scRet;		/* SSPI status */
    int			i;		/* Loop control variable */

   /*
    * Initialize security buffer structs
    */
    message.ulVersion = SECBUFFER_VERSION;
    message.cBuffers = 4;
    message.pBuffers = buffers;

    do
    {
     /*
      * If there is not enough space in the
      * buffer, then increase it's size
      */
      if (conn->decryptBufferLength <= conn->decryptBufferUsed)
      {
        conn->decryptBufferLength += 4096;
        conn->decryptBuffer = (BYTE*) realloc(conn->decryptBuffer,
                                              conn->decryptBufferLength);

        if (!conn->decryptBuffer)
        {
          DEBUG_printf(("_sspiRead: unable to allocate %d byte buffer",
                        conn->decryptBufferLength));
          WSASetLastError(E_OUTOFMEMORY);
          num = SOCKET_ERROR;
          goto cleanup;
        }
      }

      buffers[0].pvBuffer	= conn->decryptBuffer;
      buffers[0].cbBuffer	= (unsigned long) conn->decryptBufferUsed;
      buffers[0].BufferType	= SECBUFFER_DATA;
      buffers[1].BufferType	= SECBUFFER_EMPTY;
      buffers[2].BufferType	= SECBUFFER_EMPTY;
      buffers[3].BufferType	= SECBUFFER_EMPTY;

      scRet = DecryptMessage(&conn->context, &message, 0, NULL);

      if (scRet == SEC_E_INCOMPLETE_MESSAGE)
      {
        if (buf)
        {
          num = recv(conn->sock,
                     conn->decryptBuffer + conn->decryptBufferUsed,
                     (int)(conn->decryptBufferLength - conn->decryptBufferUsed),
                     0);
          if (num == SOCKET_ERROR)
          {
            DEBUG_printf(("_sspiRead: recv failed: %d", WSAGetLastError()));
            goto cleanup;
          }
          else if (num == 0)
          {
            DEBUG_printf(("_sspiRead: server disconnected"));
            goto cleanup;
          }

          conn->decryptBufferUsed += num;
        }
        else
        {
          num = (int) conn->readBufferUsed;
          goto cleanup;
        }
      }
    }
    while (scRet == SEC_E_INCOMPLETE_MESSAGE);

    if (scRet == SEC_I_CONTEXT_EXPIRED)
    {
      DEBUG_printf(("_sspiRead: context expired"));
      WSASetLastError(WSAECONNRESET);
      num = SOCKET_ERROR;
      goto cleanup;
    }
    else if (scRet != SEC_E_OK)
    {
      DEBUG_printf(("_sspiRead: DecryptMessage failed: %lx", scRet));
      WSASetLastError(WSASYSCALLFAILURE);
      num = SOCKET_ERROR;
      goto cleanup;
    }

   /*
    * The decryption worked.  Now, locate data buffer.
    */
    pDataBuffer  = NULL;
    pExtraBuffer = NULL;
    for (i = 1; i < 4; i++)
    {
      if (buffers[i].BufferType == SECBUFFER_DATA)
        pDataBuffer = &buffers[i];
      else if (!pExtraBuffer && (buffers[i].BufferType == SECBUFFER_EXTRA))
        pExtraBuffer = &buffers[i];
    }

   /*
    * If a data buffer is found, then copy
    * the decrypted bytes to the passed-in
    * buffer
    */
    if (pDataBuffer)
    {
      int bytesToCopy = min(pDataBuffer->cbBuffer, (int) len);
                           		/* Number of bytes to copy into buf */
      int bytesToSave = pDataBuffer->cbBuffer - bytesToCopy;
                           		/* Number of bytes to save in our read buffer */

      if (bytesToCopy)
        memcpy(buf, pDataBuffer->pvBuffer, bytesToCopy);

     /*
      * If there are more decrypted bytes than can be
      * copied to the passed in buffer, then save them
      */
      if (bytesToSave)
      {
        if ((int)(conn->readBufferLength - conn->readBufferUsed) < bytesToSave)
        {
          conn->readBufferLength = conn->readBufferUsed + bytesToSave;
          conn->readBuffer = realloc(conn->readBuffer,
                                     conn->readBufferLength);

          if (!conn->readBuffer)
          {
            DEBUG_printf(("_sspiRead: unable to allocate %d bytes", conn->readBufferLength));
            WSASetLastError(E_OUTOFMEMORY);
            num = SOCKET_ERROR;
            goto cleanup;
          }
        }

        memcpy(((BYTE*) conn->readBuffer) + conn->readBufferUsed,
               ((BYTE*) pDataBuffer->pvBuffer) + bytesToCopy,
               bytesToSave);

        conn->readBufferUsed += bytesToSave;
      }

      num = (buf) ? bytesToCopy : (int) conn->readBufferUsed;
    }
    else
    {
      DEBUG_printf(("_sspiRead: unable to find data buffer"));
      WSASetLastError(WSASYSCALLFAILURE);
      num = SOCKET_ERROR;
      goto cleanup;
    }

   /*
    * If the decryption process left extra bytes,
    * then save those back in decryptBuffer. They will
    * be processed the next time through the loop.
    */
    if (pExtraBuffer)
    {
      memmove(conn->decryptBuffer, pExtraBuffer->pvBuffer, pExtraBuffer->cbBuffer);
      conn->decryptBufferUsed = pExtraBuffer->cbBuffer;
    }
    else
    {
      conn->decryptBufferUsed = 0;
    }
  }

cleanup:

  return (num);
}
Example #27
0
int mcpOpen(char *name)
{
  char host[MAXHOSTNAMELEN], service[MAXHOSTNAMELEN];

  char buf[1024];

  char *cptr;
  int count, status;

  int sock_fd;
  struct hostent *hp;
  struct servent *sp;
  struct in_addr tmpaddr;
  int optval;

  struct sockaddr_in	inet_a;  // inet_addr is a function name

#ifndef _WIN32
  char path[MAXPATHLEN];
  struct sockaddr_un	unix_addr;
  size_t		unix_addr_len;

#endif //WIN32

#ifdef _WIN32
  // make sure we are initialized
  extern struct { int initialized; } initializer;
  if (initializer.initialized == 0)
	  return -1;
#endif //WIN32

  /*
   * Parse the name string.
   *
   *  A. If there is a ':' then it is an internet socket connection.
   *	1. Parse the name into <host>:<service> format.
   *	  a. If host is empty, use "localhost".
   *	  b. Lookup service with getservbyname().  If found, use
   *	     that port value.  If not found, attempt to convert
   *	     it to an integer and use that port value.
   *	2. Connect to <host>:<port>.  If the connection fails,
   *	   attempt to connect to <host>:tcpmux then request <service>
   *	   from tcpmux.
   *  B. Else the name is a unix domain socket name.
   *    1. If the first character is not '/', prepend '/tmp/' to the
   *	   name string.
   *	2. Connect to the socket name.
   */

  cptr = strchr(name, ':');

  if (cptr)
  {
    /* Copy the host name */
    if (cptr == name)
    {
      strcpy(host, "localhost");
    }
    else
    {
      strncpy(host, name, (cptr - name));
      host[cptr-name] = '\0';
    }

    /* Copy the service name */
    strcpy(service, cptr + 1);

    /* Initialize the inet_a struct */
    bzero((char *) &inet_a, sizeof(inet_a));
    inet_a.sin_family = AF_INET;

    /* Attempt to convert the host address as a dotted decimal number */
#ifdef _WIN32
    tmpaddr.s_addr = inet_addr(host);
    status = (tmpaddr.s_addr != INADDR_NONE) ? 1 : 0;
#else
    status = inet_aton(host, &tmpaddr);
#endif //WIN32
    if (status == 1)
    {
      bcopy((char *) &tmpaddr, (char *) &inet_a.sin_addr, sizeof(tmpaddr));
    }
    else
    {
      /* Now find the host */
      hp = gethostbyname(host);

      if (!hp)
      {
	/* We could not find the host */
	errno = ENOENT;
	return -1;
      }

      bcopy(hp->h_addr, (char *) &inet_a.sin_addr, hp->h_length);
    }

    /* Attempt to decode the service parameter */
    sp = getservbyname(service, "tcp");

    if (sp)
    {
      inet_a.sin_port = sp->s_port;
    }
    else
    {
      /* Attempt to convert the service name as an integer */
      inet_a.sin_port = htons((unsigned short)atoi(service));
    }

    /* Create the socket */
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_fd < 0)
    {
      return -1;
    }

    status = connect(sock_fd, (struct sockaddr *) &inet_a,
                     sizeof(inet_a));

    if (status < 0)
    {
      int status2;
      /*
       * The connection failed, try connecting to the tcpmux service.
       * tcpmux is at the well known port 1 so I just hardcoded it.
       */
      inet_a.sin_port = htons(1);

      status = errno;
      status2 = connect(sock_fd, (struct sockaddr *) &inet_a,
                        sizeof(inet_a));
      if (status2 < 0)
      {
		closefd(sock_fd);
		errno = status;
		return -1;
      }

      /*
       * We connected to tcpmux, now send the service name and see if
       * tcpmux can give it to us.  The tcpmux protocol works as follows:
       *
       *  1 Connect to the tcpmux port
       *  2 write the name of the service that you want followed by <CRLF>.
       *  3 read back the response terminated by <CRLF>
       *    a If the first character is a '+' then we are connected.
       *    b if the first character is a '-' then we are not connected.
       */
      sprintf(buf, "%s\r\n", service);
      status = mcpWrite(sock_fd, buf, (unsigned int) strlen(buf));
      if (status != (int)strlen(buf))
      {
		status = errno;
		closefd(sock_fd);
		errno = status;
		return -1;
      }

      /* Read up through the <CRLF> pair */
      /* There will be at least 3 characters coming back */
      cptr = buf;
      count = 3;
      while (1)
      {
		status = mcpRead(sock_fd, cptr, count);
		if (status <= 0)
		{
		  status = errno;
		  closefd(sock_fd);
		  errno = status;
		  return -1;
		}

		cptr += status;
		if (cptr[-1] == '\n')
		{
		  break;
		}
		else if (cptr[-1] == '\r')
		{
		  count = 1;
		}
		else
		{
		  count = 2;
		}
      }

      if (buf[0] != '+')
      {
		closefd(sock_fd);
#ifdef _WIN32
		errno = WSAECONNREFUSED;
		WSASetLastError (WSAECONNREFUSED);
#else
		errno = ECONNREFUSED;
#endif //WIN32
		return -1;
	  }
    }

    /*
     * We did it!  We actually succeeded in connecting to the name
     * via internet sockets.  Now make sure that we can send small
     * packets without delay.
     */
    optval = 1;
    status = setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&optval,
			sizeof(optval));
  }
  else /* This must be a unix domain socket name */
  {
#ifndef _WIN32 // {
    /* Initialize the unix_addr struct */
    bzero((char *) &unix_addr, sizeof(unix_addr));
    unix_addr.sun_family = AF_UNIX;

    /*
     * If there is a leading '/' in the name name, it is an
     * absolute path name, otherwise, it is relative to /tmp.
     */
    if (name[0] == '/')
    {
      strcpy(path, name);
    }
    else
    {
      sprintf(path, "/tmp/%s", name);
    }

    strcpy(unix_addr.sun_path, path);
    unix_addr_len = sizeof(unix_addr.sun_len) + sizeof(unix_addr.sun_family) + strlen(path);

    /* Create the socket */
    sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock_fd < 0)
    {
      return -1;
    }

    /* Connect to the name */
    status = connect(sock_fd, (struct sockaddr *) &unix_addr, unix_addr_len);
    if (status < 0)
    {
      closefd(sock_fd);
      return -1;
    }

    /*
     * We did it!  We actually succeeded in connecting to the name
     * via unix sockets.
     */
#else // } {
	HANDLE h;
	void* pmem;
	DWORD *mask, bit;
	struct sockmap* map;
	int i;
	
	h = CreateFileMapping(INVALID_HANDLE_VALUE, 0, 
		PAGE_READWRITE,
		0, MAYA_UNIX_SOCKET_SHARE_SIZE,
		MAYA_UNIX_SOCKET_SHARE_NAME);
	if (!h)
		return -1;
	if (GetLastError() != ERROR_ALREADY_EXISTS)
	{
		/* no "unix" handles exist */
		CloseHandle(h);
		return -1;
	}
	
	pmem = MapViewOfFile(h, FILE_MAP_WRITE,	0, 0, 0);
	if (!pmem)
	{
		CloseHandle(h);
		return -1;
	}
	mask = (DWORD*)pmem;
	map = (struct sockmap*)((char*)pmem+sizeof(DWORD));

	/* check if name is already here */
	sock_fd = -1;
	for (bit = 1, i = 0; i < 32; ++i)
	{
		if (*mask & bit)
		{
			if (strcmp(map[i].unix_path, name) == 0)
				break; /* found */
		}
		bit = bit << 1;
	}
	
	/* found */
	if (i < 32)
	{
		/* Initialize the inet_a struct */
		bzero((char *) &inet_a, sizeof(inet_a));
		inet_a.sin_family = AF_INET;

		/* Now find the host */
		hp = gethostbyname("localhost");
		if (!hp)
			errno = ENOENT;
		else
		{
			bcopy(hp->h_addr, (char *) &inet_a.sin_addr, hp->h_length);
			inet_a.sin_port = map[i].port;

			/* Create the socket */
			sock_fd = socket(AF_INET, SOCK_STREAM, 0);
			if (sock_fd >= 0)
			{
				status = connect(sock_fd, (struct sockaddr*)&inet_a, sizeof(inet_a));
				if (status < 0)
				{
					closefd(sock_fd);
					sock_fd = -1;
					errno = status;
				}
				else
				{
					optval = 1;
					status = setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY,
						(char*)&optval, sizeof(optval));
				}
			}
		}
	}

	UnmapViewOfFile(pmem);
	CloseHandle(h);

#endif //WIN32 }
  }

  /* Ok, we are connected.  Return the socket descriptor */
  return sock_fd;
}
Example #28
0
/* Initialize a dac_conn_t and connect to the DAC.
 *
 * On success, return 0.
 */
int dac_connect(dac_t *d, const char *host, const char *port) {
	dac_conn_t *conn = &d->conn;
	ZeroMemory(conn, sizeof(d->conn));

	// Look up the server address
	struct addrinfo *result = NULL, *ptr = NULL, hints;
	ZeroMemory(&hints, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	trace(d, "Calling getaddrinfo: \"%s\", \"%s\"\n", host, port);

	int res = getaddrinfo(host, port, &hints, &result);
	if (res != 0) {
		trace(d, "getaddrinfo failed: %d\n", res);
		return -1;
	}

	// Create a SOCKET
	ptr = result;
	conn->sock = socket(ptr->ai_family, ptr->ai_socktype, 
		ptr->ai_protocol);

	if (conn->sock == INVALID_SOCKET) {
		log_socket_error(d, "socket");
		freeaddrinfo(result);
		return -1;
	}

	unsigned long nonblocking = 1;
	ioctlsocket(conn->sock, FIONBIO, &nonblocking);

	memset(&conn->udp_target, 0, sizeof(conn->udp_target));
	conn->udp_target.sin_family = AF_INET;
	conn->udp_target.sin_addr.s_addr = ((struct sockaddr_in *)(ptr->ai_addr))->sin_addr.s_addr;
	conn->udp_target.sin_port = htons(60000);

	// Connect to host. Because the socket is nonblocking, this
	// will always return WSAEWOULDBLOCK.
	connect(conn->sock, ptr->ai_addr, (int)ptr->ai_addrlen);
	freeaddrinfo(result);

	if (WSAGetLastError() != WSAEWOULDBLOCK) {
		log_socket_error(d, "connect");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	// Wait for connection.
	fd_set set;
	FD_ZERO(&set);
	FD_SET(conn->sock, &set);
	struct timeval time;
	time.tv_sec = 0;
	time.tv_usec = DEFAULT_TIMEOUT;
	res = select(0, &set, &set, &set, &time);

	if (res == SOCKET_ERROR) {
		log_socket_error(d, "select");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	} else if (res == 0) {
		trace(d, "Connection to %s timed out.\n", host);
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	// See if we have *actually* connected
	int error;
	int len = sizeof(error);
	if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *)&error, &len) ==
			SOCKET_ERROR) {
		log_socket_error(d, "getsockopt");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	if (error) {
		WSASetLastError(error);
		log_socket_error(d, "connect");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	BOOL ndelay = 1;
	res = setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
		(char *)&ndelay, sizeof(ndelay));
	if (res == SOCKET_ERROR) {
		log_socket_error(d, "setsockopt TCP_NODELAY");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	trace(d, "Connected.\n");

	// Create socket for OSC
	conn->udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (conn->udp_sock == INVALID_SOCKET) {
		log_socket_error(d, "socket(AF_INET, SOCK_DRGAM)");
	} else {
		res = connect(conn->udp_sock, (struct sockaddr *)&conn->udp_target, sizeof(conn->udp_target));
		if (res == SOCKET_ERROR) {
			log_socket_error(d, "connect(udp_sock)");
		}
	}

	nonblocking = 1;
	ioctlsocket(conn->udp_sock, FIONBIO, &nonblocking);

	// After we connect, the host will send an initial status response. 
	dac_read_resp(d, DEFAULT_TIMEOUT);
	dac_dump_resp(d);

	char c = 'p';
	dac_sendall(d, &c, 1);
	dac_read_resp(d, DEFAULT_TIMEOUT);
	dac_dump_resp(d);

	if (d->sw_revision >= 2) {
		c = 'v';
		dac_sendall(d, &c, 1);
		res = dac_read_bytes(d, d->version, sizeof(d->version));
		if (res < 0)
			return res;

		trace(d, "DAC version: %.*s\n", sizeof(d->version), d->version);
	} else {
		memset(d->version, 0, sizeof(d->version));
		trace(d, "DAC version old!\n");
	}

	return 0;
}
Example #29
0
File: socket.c Project: djs55/qemu
/*
 * Listen for incoming TCP connections
 */
struct socket *
tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
           u_int lport, int flags)
{
	struct sockaddr_in addr;
	struct socket *so;
	int s, opt = 1;
	socklen_t addrlen = sizeof(addr);
	memset(&addr, 0, addrlen);

	DEBUG_CALL("tcp_listen");
	DEBUG_ARG("haddr = %x", haddr);
	DEBUG_ARG("hport = %d", hport);
	DEBUG_ARG("laddr = %x", laddr);
	DEBUG_ARG("lport = %d", lport);
	DEBUG_ARG("flags = %x", flags);

	so = socreate(slirp);
	if (!so) {
	  return NULL;
	}

	/* Don't tcp_attach... we don't need so_snd nor so_rcv */
	if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
		free(so);
		return NULL;
	}
	insque(so, &slirp->tcb);

	/*
	 * SS_FACCEPTONCE sockets must time out.
	 */
	if (flags & SS_FACCEPTONCE)
	   so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;

	so->so_state &= SS_PERSISTENT_MASK;
	so->so_state |= (SS_FACCEPTCONN | flags);
	so->so_lport = lport; /* Kept in network format */
	so->so_laddr.s_addr = laddr; /* Ditto */

	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = haddr;
	addr.sin_port = hport;

	if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
	    (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
	    (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
	    (listen(s,1) < 0)) {
		int tmperrno = errno; /* Don't clobber the real reason we failed */

		close(s);
		sofree(so);
		/* Restore the real errno */
#ifdef _WIN32
		WSASetLastError(tmperrno);
#else
		errno = tmperrno;
#endif
		return NULL;
	}
	setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));

	getsockname(s,(struct sockaddr *)&addr,&addrlen);
	so->so_fport = addr.sin_port;
	if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
	   so->so_faddr = slirp->vhost_addr;
	else
	   so->so_faddr = addr.sin_addr;

	so->s = s;
	return so;
}
Example #30
0
static void
accepted_socket_invoke_user_cb(struct deferred_cb *dcb, void *arg)
{
	struct accepting_socket *as = arg;

	struct sockaddr *sa_local=NULL, *sa_remote=NULL;
	int socklen_local=0, socklen_remote=0;
	const struct win32_extension_fns *ext = event_get_win32_extension_fns();
	struct evconnlistener *lev = &as->lev->base;
	evutil_socket_t sock=-1;
	void *data;
	evconnlistener_cb cb=NULL;
	evconnlistener_errorcb errorcb=NULL;
	int error;

	EVUTIL_ASSERT(ext->GetAcceptExSockaddrs);

	LOCK(lev);
	EnterCriticalSection(&as->lock);
	if (as->free_on_cb) {
		free_and_unlock_accepting_socket(as);
		listener_decref_and_unlock(lev);
		return;
	}

	++lev->refcnt;

	error = as->error;
	if (error) {
		as->error = 0;
		errorcb = lev->errorcb;
	} else {
		ext->GetAcceptExSockaddrs(
			as->addrbuf, 0, as->buflen/2, as->buflen/2,
			&sa_local, &socklen_local, &sa_remote,
			&socklen_remote);
		sock = as->s;
		cb = lev->cb;
		as->s = INVALID_SOCKET;

		/* We need to call this so getsockname, getpeername, and
		 * shutdown work correctly on the accepted socket. */
		/* XXXX handle error? */
		setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
		    (char *)&as->lev->fd, sizeof(&as->lev->fd));
	}
	data = lev->user_data;

	LeaveCriticalSection(&as->lock);
	UNLOCK(lev);

	if (errorcb) {
		WSASetLastError(error);
		errorcb(lev, data);
	} else if (cb) {
		cb(lev, sock, sa_remote, socklen_remote, data);
	}

	LOCK(lev);
	if (listener_decref_and_unlock(lev))
		return;

	EnterCriticalSection(&as->lock);
	start_accepting(as);
	LeaveCriticalSection(&as->lock);
}