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 }
// 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; } }
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; } }
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; }
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; }
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; }
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; }
void mono_w32socket_set_last_error (gint32 error) { WSASetLastError (error); }
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 }
/* * 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; }
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); }
/** 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 }
/*----------------------------------------------------------------------* 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 }
/* * '_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); }
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; }
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); }
/** * 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; }
/* * 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 {
/* * '_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); }
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; }
/* 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; }
/* * 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; }
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); }