void printError(const wchar_t *msg) { wprintf(L"%s error:%ld\n", msg, WSAGetLastError()); }
static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) { uv_read_t* req; uv_buf_t buf; int result; DWORD bytes, flags; assert(handle->flags & UV_HANDLE_READING); assert(!(handle->flags & UV_HANDLE_READ_PENDING)); req = &handle->read_req; memset(&req->overlapped, 0, sizeof(req->overlapped)); /* * Preallocate a read buffer if the number of active streams is below * the threshold. */ if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) { handle->flags &= ~UV_HANDLE_ZERO_READ; handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->read_buffer); if (handle->read_buffer.len == 0) { handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->read_buffer); return; } assert(handle->read_buffer.base != NULL); buf = handle->read_buffer; } else { handle->flags |= UV_HANDLE_ZERO_READ; buf.base = (char*) &uv_zero_; buf.len = 0; } /* Prepare the overlapped structure. */ memset(&(req->overlapped), 0, sizeof(req->overlapped)); if (handle->flags & UV_HANDLE_EMULATE_IOCP) { assert(req->event_handle); req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); } flags = 0; result = WSARecv(handle->socket, (WSABUF*)&buf, 1, &bytes, &flags, &req->overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Process the req without IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; req->overlapped.InternalHigh = bytes; handle->reqs_pending++; uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* The req will be processed with IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; handle->reqs_pending++; if (handle->flags & UV_HANDLE_EMULATE_IOCP && req->wait_handle == INVALID_HANDLE_VALUE && !RegisterWaitForSingleObject(&req->wait_handle, req->event_handle, post_completion, (void*) req, INFINITE, WT_EXECUTEINWAITTHREAD)) { SET_REQ_ERROR(req, GetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); } } else { /* Make this req pending reporting an error. */ SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; } }
static int uv_tcp_try_connect(uv_connect_t* req, uv_tcp_t* handle, const struct sockaddr* addr, unsigned int addrlen, uv_connect_cb cb) { uv_loop_t* loop = handle->loop; const struct sockaddr* bind_addr; BOOL success; DWORD bytes; int err; if (handle->flags & UV_HANDLE_BIND_ERROR) { return handle->bind_error; } if (!(handle->flags & UV_HANDLE_BOUND)) { if (addrlen == sizeof(uv_addr_ip4_any_)) { bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; } else if (addrlen == sizeof(uv_addr_ip6_any_)) { bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; } else { abort(); } err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0); if (err) return err; } if (!handle->func_connectex) { if (!uv_get_connectex_function(handle->socket, &handle->func_connectex)) { return WSAEAFNOSUPPORT; } } uv_req_init(loop, (uv_req_t*) req); req->type = UV_CONNECT; req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->overlapped, 0, sizeof(req->overlapped)); success = handle->func_connectex(handle->socket, addr, addrlen, NULL, 0, &bytes, &req->overlapped); if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { /* Process the req without IOCP. */ handle->reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(success)) { /* The req will be processed with IOCP. */ handle->reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); } else { return WSAGetLastError(); } return 0; }
int _getdns_event_add(struct _getdns_event *ev, struct timeval *tv) { printf( "event_add %p added=%d fd=%d tv=" ARG_LL "d %s%s%s", ev, ev->added, ev->ev_fd, (tv?(long long)tv->tv_sec*1000+(long long)tv->tv_usec/1000:-1), (ev->ev_events&EV_READ)?" EV_READ":"", (ev->ev_events&EV_WRITE)?" EV_WRITE":"", (ev->ev_events&EV_TIMEOUT)?" EV_TIMEOUT":""); if(ev->added) event_del(ev); /* gowri no works if (ev->ev_fd == -1 || find_fd(ev->ev_base, ev->ev_fd) == -1) { printf("event_add failed, bad fd\n"); return 0; } */ ev->is_tcp = 0; ev->is_signal = 0; ev->just_checked = 0; if ((ev->ev_events&(EV_READ | EV_WRITE)) && ev->ev_fd != -1) { BOOL b = 0; int t, l; long events = 0; //gprintf("\getdns_event_add %d %d\n", ev->ev_fd, events); if (ev->ev_base->max == ev->ev_base->cap) return -1; ev->idx = ev->ev_base->max++; ev->ev_base->items[ev->idx] = ev; if ((ev->ev_events&EV_READ)) events |= FD_READ; if ((ev->ev_events&EV_WRITE)) { events |= FD_CONNECT; events |= FD_WRITE; } //printf("\getdns_event_add %d read = %d write = %d %d\n", ev->ev_fd, ev->ev_events&EV_READ, ev->ev_events&EV_WRITE, events); l = sizeof(t); if(getsockopt(ev->ev_fd, SOL_SOCKET, SO_TYPE, (void*)&t, &l) != 0) log_err("getdns: getsockopt(SO_TYPE) failed: %s", wsa_strerror(WSAGetLastError())); if(t == SOCK_STREAM) { /* TCP socket */ ev->is_tcp = 1; events |= FD_CLOSE; if( (ev->ev_events&EV_WRITE) ) events |= FD_CONNECT; l = sizeof(b); if(getsockopt(ev->ev_fd, SOL_SOCKET, SO_ACCEPTCONN, (void*)&b, &l) != 0) log_err("getdns: getsockopt(SO_ACCEPTCONN) failed: %s", wsa_strerror(WSAGetLastError())); if(b) /* TCP accept socket */ events |= FD_ACCEPT; } ev->hEvent = WSACreateEvent(); if(ev->hEvent == WSA_INVALID_EVENT) log_err("getdns: WSACreateEvent failed: %s", wsa_strerror(WSAGetLastError())); /* automatically sets fd to nonblocking mode. * nonblocking cannot be disabled, until wsaES(fd, NULL, 0) */ //g printf("\nWSAEventSelect %d events %d hEvent %d\n", ev->ev_fd, events, ev->hEvent); //gg if (WSAEventSelect(ev->ev_fd, ev->hEvent, FD_ACCEPT | FD_CONNECT | FD_READ | FD_CLOSE | FD_WRITE) != 0) { //if (WSAEventSelect(ev->ev_fd, ev->hEvent,FD_READ | FD_WRITE) != 0) { if (WSAEventSelect(ev->ev_fd, ev->hEvent, events) != 0) { log_err("getdns: WSAEventSelect in getdns failed: %s", wsa_strerror(WSAGetLastError())); } if(ev->is_tcp && ev->stick_events && (ev->ev_events & ev->old_events)) { /* go to processing the sticky event right away */ ev->ev_base->tcp_reinvigorated = 1; } } if(tv && (ev->ev_events&EV_TIMEOUT)) { #ifndef S_SPLINT_S struct timeval *now = ev->ev_base->time_tv; ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec; ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec; while(ev->ev_timeout.tv_usec > 1000000) { ev->ev_timeout.tv_usec -= 1000000; ev->ev_timeout.tv_sec++; } #endif (void)_getdns_rbtree_insert(ev->ev_base->times, &ev->node); } ev->added = 1; return 0; }
static int uv_tcp_try_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int addrlen, unsigned int flags) { DWORD err; int r; if (handle->socket == INVALID_SOCKET) { SOCKET sock; /* Cannot set IPv6-only mode on non-IPv6 socket. */ if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) return ERROR_INVALID_PARAMETER; sock = socket(addr->sa_family, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { return WSAGetLastError(); } /* Make the socket non-inheritable */ if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) { err = GetLastError(); closesocket(sock); return err; } err = uv_tcp_set_socket(handle->loop, handle, sock, addr->sa_family, 0); if (err) { closesocket(sock); return err; } } #ifdef IPV6_V6ONLY if (addr->sa_family == AF_INET6) { int on; on = (flags & UV_TCP_IPV6ONLY) != 0; /* TODO: how to handle errors? This may fail if there is no ipv4 stack */ /* available, or when run on XP/2003 which have no support for dualstack */ /* sockets. For now we're silently ignoring the error. */ setsockopt(handle->socket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof on); } #endif r = bind(handle->socket, addr, addrlen); if (r == SOCKET_ERROR) { err = WSAGetLastError(); if (err == WSAEADDRINUSE) { /* Some errors are not to be reported until connect() or listen() */ handle->bind_error = err; handle->flags |= UV_HANDLE_BIND_ERROR; } else { return err; } } handle->flags |= UV_HANDLE_BOUND; return 0; }
bool CSocket::Recv( char* pszData, long nLen, bool bEmptyError /*= true*/ ) { bool bResult = false; static uint anTimeOuts[ DEFAULT_CHECK_ATTEMPTS ] = { 500, 2000, 5000 }; do { bool bLoopError = false; long nExpectedLen = 0, nRecvLen = 0, nRes = 0, nNetLen = 0; m_nBytesRead = 0; if( !nLen ) LOG_ERROR_BREAK( "Receiving buffer size is 0" ); if( !pszData ) LOG_ERROR_BREAK( "pszData is NULL" ); size_t nAttempts = 0; do { m_tvTimeOut.tv_sec = (long)anTimeOuts[nAttempts] / 1000; m_tvTimeOut.tv_usec = ( anTimeOuts[nAttempts] % 1000 ) * 1000; FD_ZERO(&m_fdReadSockets); FD_SET(m_sockMain, &m_fdReadSockets); if( SOCKET_ERROR == (nRes = select(int(m_sockMain)+1, &m_fdReadSockets, 0, 0, &m_tvTimeOut)) ) { LOG_ERROR3_BREAK( szErrorFailedWithCodeFmt, "select", WSAGetLastError() ); } } while( !nRes && m_nCheckAttempts > nAttempts++ ); if( !nRes ) break; // LOG_ERROR_BREAK( szSocketNotReady ); if( !FD_ISSET(m_sockMain, &m_fdReadSockets) ) LOG_ERROR_BREAK( "Timeout elapsed" ); nExpectedLen = nLen; if( m_bUseHeaderLength ) { nRecvLen = recv( m_sockMain, (char*)&nNetLen, sizeof(nNetLen), 0 ); if( SOCKET_ERROR == nRecvLen || !nRecvLen ) { LOG_ERROR3_BREAK( szErrorFailedWithCodeFmt, "recv", WSAGetLastError() ); } nExpectedLen = ntohl( nNetLen ); if( nExpectedLen > nLen ) { LOG_ERROR( "Too small receiving buffer" ); nExpectedLen = nLen; } //cout << nExpectedLen << " (" << nNetLen << " : " << nRecvLen << ")"; } while( nExpectedLen > 0 ) { nRecvLen = recv( m_sockMain, pszData, nExpectedLen, 0 ); if( !nRecvLen ) { if( !m_nBytesRead ) { // when it is not first read attempt we shouldn't show this error if( bEmptyError ) { LOG_ERROR( "Received 0 bytes" ); bLoopError = true; } } break; } if( SOCKET_ERROR == nRecvLen || nRecvLen < 0 ) { bLoopError = true; LOG_ERROR3_BREAK( szErrorFailedWithCodeFmt, "recv", WSAGetLastError() ); } nExpectedLen -= nRecvLen; pszData += nRecvLen; m_nBytesRead += nRecvLen; if (!nExpectedLen) { break; } sizeint siNextTimeout = m_bUseHeaderLength ? 5000 : m_nWaitNextTimeOut; if (!CanRead(siNextTimeout)) { if (m_bUseHeaderLength) { LOG_ERROR2("Wait times out %u", siNextTimeout); bLoopError = true; } break; } } bResult = !bLoopError; } while( false ); return bResult; }
/** call select and callbacks for that */ int _getdns_handle_select(struct _getdns_event_base* base, struct timeval* wait) { fd_set r, w; int ret, i, timeout = 0, numwait = 0; struct _getdns_event* eventlist[WSK_MAX_ITEMS]; #ifndef S_SPLINT_S if (wait->tv_sec == (time_t)-1) wait = NULL; #endif memmove(&r, &base->reads, sizeof(fd_set)); memmove(&w, &base->writes, sizeof(fd_set)); memmove(&base->ready, &base->content, sizeof(fd_set)); /* if ((ret = select(base->max + 1, &r, &w, NULL, wait)) == -1) { ret = errno; if (settime(base) < 0) return -1; errno = ret; if (ret == EAGAIN || ret == EINTR) return 0; return -1; } */ /* prepare event array */ for (i = 0; i<base->max; i++) { if (base->items[i]->ev_fd == -1 && !base->items[i]->is_signal) continue; /* skip timer only events */ eventlist[numwait] = base->items[i]; base->waitfor[numwait++] = base->items[i]->hEvent; if (numwait == WSK_MAX_ITEMS) break; /* sanity check */ } ret = WSAWaitForMultipleEvents(base->max, base->waitfor, 0 /* do not wait for all, just one will do */, wait ? timeout : WSA_INFINITE, 0); /* we are not alertable (IO completion events) */ if (ret == WSA_WAIT_IO_COMPLETION) { log_err("getdns: WSAWaitForMultipleEvents failed: WSA_WAIT_IO_COMPLETION"); return -1; } else if (ret == WSA_WAIT_FAILED) { log_err("getdns: WSAWaitForMultipleEvents failed: %s", wsa_strerror(WSAGetLastError())); return -1; } else if (ret == WSA_WAIT_TIMEOUT) { was_timeout = 1; } else startidx = ret - WSA_WAIT_EVENT_0; if (settime(base) < 0) return -1; for (i = 0; i<base->max + 1; i++) { short bits = 0; if (!base->items[i] || !(FD_ISSET(i, &base->ready))) { continue; } if (FD_ISSET(i, &r)) { bits |= EV_READ; ret--; } if (FD_ISSET(i, &w)) { bits |= EV_WRITE; ret--; } bits &= base->items[i]->ev_events; if (bits) { fptr_ok(fptr_whitelist_event( base->items[i]->ev_callback)); (*base->items[i]->ev_callback)(base->items[i]->ev_fd, bits, base->items[i]->ev_arg); if (ret == 0) break; } } return 0; }
void Listener::initAndListen() { checkTicketNumbers(); vector<SOCKET> socks; { vector<SockAddr> mine = ipToAddrs(_ip.c_str(), _port, false); if ( ! _setupSockets( mine , socks ) ) return; } #ifdef MONGO_SSL _logListen(_port, _ssl); #else _logListen(_port, false); #endif OwnedPointerVector<EventHolder> eventHolders; boost::scoped_array<WSAEVENT> events(new WSAEVENT[socks.size()]); // Populate events array with an event for each socket we are watching for (size_t count = 0; count < socks.size(); ++count) { EventHolder* ev(new EventHolder); eventHolders.mutableVector().push_back(ev); events[count] = ev->get(); } while ( ! inShutdown() ) { // Turn on listening for accept-ready sockets for (size_t count = 0; count < socks.size(); ++count) { int status = WSAEventSelect(socks[count], events[count], FD_ACCEPT | FD_CLOSE); if (status == SOCKET_ERROR) { const int mongo_errno = WSAGetLastError(); error() << "Windows WSAEventSelect returned " << errnoWithDescription(mongo_errno) << endl; fassertFailed(16727); } } // Wait till one of them goes active, or we time out DWORD result = WSAWaitForMultipleEvents(socks.size(), events.get(), FALSE, // don't wait for all the events 10, // timeout, in ms FALSE); // do not allow I/O interruptions if (result == WSA_WAIT_FAILED) { const int mongo_errno = WSAGetLastError(); error() << "Windows WSAWaitForMultipleEvents returned " << errnoWithDescription(mongo_errno) << endl; fassertFailed(16723); } if (result == WSA_WAIT_TIMEOUT) { _elapsedTime += 10; continue; } _elapsedTime += 1; // assume 1ms to grab connection. very rough // Determine which socket is ready DWORD eventIndex = result - WSA_WAIT_EVENT_0; WSANETWORKEVENTS networkEvents; // Extract event details, and clear event for next pass int status = WSAEnumNetworkEvents(socks[eventIndex], events[eventIndex], &networkEvents); if (status == SOCKET_ERROR) { const int mongo_errno = WSAGetLastError(); error() << "Windows WSAEnumNetworkEvents returned " << errnoWithDescription(mongo_errno) << endl; continue; } if (networkEvents.lNetworkEvents & FD_CLOSE) { log() << "listen socket closed" << endl; break; } if (!(networkEvents.lNetworkEvents & FD_ACCEPT)) { error() << "Unexpected network event: " << networkEvents.lNetworkEvents << endl; continue; } int iec = networkEvents.iErrorCode[FD_ACCEPT_BIT]; if (iec != 0) { error() << "Windows socket accept did not work:" << errnoWithDescription(iec) << endl; continue; } status = WSAEventSelect(socks[eventIndex], NULL, 0); if (status == SOCKET_ERROR) { const int mongo_errno = WSAGetLastError(); error() << "Windows WSAEventSelect returned " << errnoWithDescription(mongo_errno) << endl; continue; } disableNonblockingMode(socks[eventIndex]); SockAddr from; int s = accept(socks[eventIndex], from.raw(), &from.addressSize); if ( s < 0 ) { int x = errno; // so no global issues if ( x == ECONNABORTED || x == EBADF ) { log() << "Listener on port " << _port << " aborted" << endl; return; } if ( x == 0 && inShutdown() ) { return; // socket closed } if( !inShutdown() ) { log() << "Listener: accept() returns " << s << " " << errnoWithDescription(x) << endl; if (x == EMFILE || x == ENFILE) { // Connection still in listen queue but we can't accept it yet error() << "Out of file descriptors. Waiting one second before" " trying to accept more connections." << warnings; sleepsecs(1); } } continue; } if (from.getType() != AF_UNIX) disableNagle(s); long long myConnectionNumber = globalConnectionNumber.addAndFetch(1); if ( _logConnect && ! cmdLine.quiet ){ int conns = globalTicketHolder.used()+1; const char* word = (conns == 1 ? " connection" : " connections"); log() << "connection accepted from " << from.toString() << " #" << myConnectionNumber << " (" << conns << word << " now open)" << endl; } boost::shared_ptr<Socket> pnewSock( new Socket(s, from) ); #ifdef MONGO_SSL if (_ssl) { pnewSock->secureAccepted(_ssl); } #endif accepted( pnewSock , myConnectionNumber ); } }
int libnet_write_raw_ipv4(libnet_t *l, const uint8_t *packet, uint32_t size) { int c; struct sockaddr_in sin; struct libnet_ipv4_hdr *ip_hdr; if (l == NULL) { return (-1); } ip_hdr = (struct libnet_ipv4_hdr *)packet; #if (LIBNET_BSD_BYTE_SWAP) /* * For link access, we don't need to worry about the inconsistencies of * certain BSD kernels. However, raw socket nuances abound. Certain * BSD implmentations require the ip_len and ip_off fields to be in host * byte order. */ ip_hdr->ip_len = FIX(ip_hdr->ip_len); ip_hdr->ip_off = FIX(ip_hdr->ip_off); #endif /* LIBNET_BSD_BYTE_SWAP */ memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = ip_hdr->ip_dst.s_addr; #if (__WIN32__) /* set port for TCP */ /* * XXX - should first check to see if there's a pblock for a TCP * header, if not we can use a dummy value for the port. */ if (ip_hdr->ip_p == 6) { struct libnet_tcp_hdr *tcph_p = (struct libnet_tcp_hdr *)(packet + (ip_hdr->ip_hl << 2)); sin.sin_port = tcph_p->th_dport; } /* set port for UDP */ /* * XXX - should first check to see if there's a pblock for a UDP * header, if not we can use a dummy value for the port. */ else if (ip_hdr->ip_p == 17) { struct libnet_udp_hdr *udph_p = (struct libnet_udp_hdr *)(packet + (ip_hdr->ip_hl << 2)); sin.sin_port = udph_p->uh_dport; } #endif /* __WIN32__ */ c = sendto(l->fd, packet, size, 0, (struct sockaddr *)&sin, sizeof(sin)); #if (LIBNET_BSD_BYTE_SWAP) ip_hdr->ip_len = UNFIX(ip_hdr->ip_len); ip_hdr->ip_off = UNFIX(ip_hdr->ip_off); #endif /* LIBNET_BSD_BYTE_SWAP */ if (c != size) { #if !(__WIN32__) snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): %d bytes written (%s)", __func__, c, strerror(errno)); #else /* __WIN32__ */ snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): %d bytes written (%d)", __func__, c, WSAGetLastError()); #endif /* !__WIN32__ */ } return (c); }
/*@ beasy_send - send Parameters: + int bfd - bsocket . char *buffer - buffer - int length - length Notes: @*/ int beasy_send(int bfd, char *buffer, int length) { #ifdef HAVE_WINSOCK2_H int error; int num_sent; while ((num_sent = write(bfd, buffer, length)) == SOCKET_ERROR) { error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) { //Sleep(0); continue; } if (error == WSAENOBUFS) { // If there is no buffer space available then split the buffer in half and send each piece separately. if (beasy_send(bfd, buffer, length/2) == SOCKET_ERROR) return SOCKET_ERROR; if (beasy_send(bfd, buffer+(length/2), length - (length/2)) == SOCKET_ERROR) return SOCKET_ERROR; return length; } WSASetLastError(error); return SOCKET_ERROR; } return length; #else int ret_val; int num_written; bfd_set writefds; int total = length; num_written = write(bfd, buffer, length); if (num_written == SOCKET_ERROR) { if ((errno != EINTR) || (errno != EAGAIN)) return SOCKET_ERROR; } else { length -= num_written; buffer += num_written; } while (length) { BFD_ZERO(&writefds); BFD_SET(bfd, &writefds); ret_val = bselect(1, NULL, &writefds, NULL, NULL); if (ret_val == 1) { num_written = write(((BFD_Buffer*)bfd)->real_fd, buffer, length); if (num_written == SOCKET_ERROR) { if ((errno != EINTR) || (errno != EAGAIN)) return SOCKET_ERROR; } else { if (num_written == 0) { //printf("beasy_send: socket closed\n"); return total - length; } length -= num_written; buffer += num_written; } } else { if (ret_val == SOCKET_ERROR) { if ((errno != EINTR) || (errno != EAGAIN)) return SOCKET_ERROR; } } } return total; #endif }
/*@ beasy_connect - connect Parameters: + int bfd - bsocket . char *host - hostname . int port - port - int seconds - timeout value in seconds Notes: @*/ int beasy_connect_timeout(int bfd, char *host, int port, int seconds) { #ifdef HAVE_WINSOCK2_H BOOL b; #endif clock_t start, current; int error; int reps = 0; struct hostent *lphost; struct sockaddr_in sockAddr; #ifdef USE_LINGER_SOCKOPT struct linger linger; #endif #ifdef HAVE_WINSOCK2_H /* use this array to make sure the warning only gets logged once */ BOOL bWarningLogged[4] = { FALSE, FALSE, FALSE, FALSE }; #endif start = clock(); memset(&sockAddr,0,sizeof(sockAddr)); sockAddr.sin_family = AF_INET; sockAddr.sin_addr.s_addr = inet_addr(host); if (sockAddr.sin_addr.s_addr == INADDR_NONE || sockAddr.sin_addr.s_addr == 0) { lphost = gethostbyname(host); if (lphost != NULL) sockAddr.sin_addr.s_addr = ((struct in_addr *)lphost->h_addr)->s_addr; else return SOCKET_ERROR; } sockAddr.sin_port = htons((u_short)port); while (bconnect(bfd, (SOCKADDR*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR) { current = clock(); if (((current - start) / CLOCKS_PER_SEC) > seconds) { #ifdef HAVE_WINSOCK2_H WSASetLastError(WSAETIMEDOUT); #endif return SOCKET_ERROR; } #ifdef HAVE_WINSOCK2_H error = WSAGetLastError(); srand(clock()); if( (error == WSAECONNREFUSED || error == WSAETIMEDOUT || error == WSAENETUNREACH || error == WSAEADDRINUSE) && (reps < g_beasy_connection_attempts) ) { double d = (double)rand() / (double)RAND_MAX; Sleep(200 + (int)(d*200)); reps++; switch (error) { case WSAECONNREFUSED: if (!bWarningLogged[0]) { /*log_warning("WSAECONNREFUSED error, re-attempting bconnect(%s)", host);*/ bWarningLogged[0] = TRUE; } break; case WSAETIMEDOUT: if (!bWarningLogged[1]) { log_warning("WSAETIMEDOUT error, re-attempting bconnect(%s)", host); bWarningLogged[1] = TRUE; } break; case WSAENETUNREACH: if (!bWarningLogged[2]) { log_warning("WSAENETUNREACH error, re-attempting bconnect(%s)", host); bWarningLogged[2] = TRUE; } break; case WSAEADDRINUSE: if (!bWarningLogged[3]) { log_warning("WSAEADDRINUSE error, re-attempting bconnect(%s)", host); bWarningLogged[3] = TRUE; } break; default: log_warning("%d error, re-attempting bconnect"); break; } } else { return SOCKET_ERROR; } #else if( (errno == ECONNREFUSED || errno == ETIMEDOUT || errno == ENETUNREACH) && (reps < g_beasy_connection_attempts) ) { #ifdef HAVE_USLEEP usleep(200); #else sleep(0); #endif reps++; } else { return SOCKET_ERROR; } #endif } #ifdef USE_LINGER_SOCKOPT /* Set the linger on close option */ linger.l_onoff = 1 ; linger.l_linger = 60; bsetsockopt(bfd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger)); #endif #ifdef HAVE_WINSOCK2_H b = TRUE; bsetsockopt(bfd, IPPROTO_TCP, TCP_NODELAY, (char*)&b, sizeof(BOOL)); #endif return 0; }
int main(int argc, char *argv[]) { WSADATA wsa_data; SOCKET echo_soc = 0; SOCKET accept_soc = 0; struct sockaddr_in serv_addr, client_addr; unsigned short port = ECHO_DEF_PORT; int result = 0; int addr_len = sizeof(struct sockaddr_in); char recv_buf[ECHO_BUF_SIZE]; if (argc == 2) { port = atoi(argv[1]); } WSAStartup(MAKEWORD(2,0), &wsa_data); echo_soc = socket(AF_INET, SOCK_STREAM, 0); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(port); serv_addr.sin_addr.s_addr = INADDR_ANY; result = bind(echo_soc, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); if (result == SOCKET_ERROR) { printf("[EchoServer] bind error: %d\n", WSAGetLastError()); closesocket(echo_soc); WSACleanup(); return -1; } listen(echo_soc, SOMAXCONN); printf("[EchoServer] running on port %d ...\n", port); while (1) { accept_soc = accept(echo_soc, (struct sockaddr *)&client_addr, &addr_len); if (accept_soc == INVALID_SOCKET) { printf("[EchoServer] accept error: %d\n", WSAGetLastError()); break; } result = recv(accept_soc, recv_buf, ECHO_BUF_SIZE, 0); if (result > 0) { recv_buf[result] = 0; printf("[EchoServer] recv: \"%s\", from %s\n", recv_buf, inet_ntoa(client_addr.sin_addr)); result = send(accept_soc, recv_buf, result, 0); } closesocket(accept_soc); } closesocket(echo_soc); WSACleanup(); return 0; }
int zmq::make_fdpair (fd_t *r_, fd_t *w_) { #if defined ZMQ_HAVE_EVENTFD int flags = 0; #if defined ZMQ_HAVE_EVENTFD_CLOEXEC // Setting this option result in sane behaviour when exec() functions // are used. Old sockets are closed and don't block TCP ports, avoid // leaks, etc. flags |= EFD_CLOEXEC; #endif fd_t fd = eventfd (0, flags); if (fd == -1) { errno_assert (errno == ENFILE || errno == EMFILE); *w_ = *r_ = -1; return -1; } else { *w_ = *r_ = fd; return 0; } #elif defined ZMQ_HAVE_WINDOWS #if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP // Windows CE does not manage security attributes SECURITY_DESCRIPTOR sd; SECURITY_ATTRIBUTES sa; memset (&sd, 0, sizeof sd); memset (&sa, 0, sizeof sa); InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl (&sd, TRUE, 0, FALSE); sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = &sd; #endif // This function has to be in a system-wide critical section so that // two instances of the library don't accidentally create signaler // crossing the process boundary. // We'll use named event object to implement the critical section. // Note that if the event object already exists, the CreateEvent requests // EVENT_ALL_ACCESS access right. If this fails, we try to open // the event object asking for SYNCHRONIZE access only. HANDLE sync = NULL; // Create critical section only if using fixed signaler port // Use problematic Event implementation for compatibility if using old port 5905. // Otherwise use Mutex implementation. int event_signaler_port = 5905; if (signaler_port == event_signaler_port) { #if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP sync = CreateEventW (&sa, FALSE, TRUE, L"Global\\zmq-signaler-port-sync"); #else sync = CreateEventW (NULL, FALSE, TRUE, L"Global\\zmq-signaler-port-sync"); #endif if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED) sync = OpenEventW (SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, L"Global\\zmq-signaler-port-sync"); win_assert (sync != NULL); } else if (signaler_port != 0) { wchar_t mutex_name[MAX_PATH]; #ifdef __MINGW32__ _snwprintf (mutex_name, MAX_PATH, L"Global\\zmq-signaler-port-%d", signaler_port); #else swprintf (mutex_name, MAX_PATH, L"Global\\zmq-signaler-port-%d", signaler_port); #endif #if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP sync = CreateMutexW (&sa, FALSE, mutex_name); #else sync = CreateMutexW (NULL, FALSE, mutex_name); #endif if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED) sync = OpenMutexW (SYNCHRONIZE, FALSE, mutex_name); win_assert (sync != NULL); } // Windows has no 'socketpair' function. CreatePipe is no good as pipe // handles cannot be polled on. Here we create the socketpair by hand. *w_ = INVALID_SOCKET; *r_ = INVALID_SOCKET; // Create listening socket. SOCKET listener; listener = open_socket (AF_INET, SOCK_STREAM, 0); wsa_assert (listener != INVALID_SOCKET); // Set SO_REUSEADDR and TCP_NODELAY on listening socket. BOOL so_reuseaddr = 1; int rc = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *> (&so_reuseaddr), sizeof so_reuseaddr); wsa_assert (rc != SOCKET_ERROR); tune_socket (listener); // Init sockaddr to signaler port. struct sockaddr_in addr; memset (&addr, 0, sizeof addr); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); addr.sin_port = htons (signaler_port); // Create the writer socket. *w_ = open_socket (AF_INET, SOCK_STREAM, 0); wsa_assert (*w_ != INVALID_SOCKET); // Set TCP_NODELAY on writer socket. tune_socket (*w_); if (sync != NULL) { // Enter the critical section. DWORD dwrc = WaitForSingleObject (sync, INFINITE); zmq_assert (dwrc == WAIT_OBJECT_0 || dwrc == WAIT_ABANDONED); } // Bind listening socket to signaler port. rc = bind (listener, reinterpret_cast<const struct sockaddr *> (&addr), sizeof addr); if (rc != SOCKET_ERROR && signaler_port == 0) { // Retrieve ephemeral port number int addrlen = sizeof addr; rc = getsockname (listener, reinterpret_cast<struct sockaddr *> (&addr), &addrlen); } // Listen for incoming connections. if (rc != SOCKET_ERROR) rc = listen (listener, 1); // Connect writer to the listener. if (rc != SOCKET_ERROR) rc = connect (*w_, reinterpret_cast<struct sockaddr *> (&addr), sizeof addr); // Accept connection from writer. if (rc != SOCKET_ERROR) *r_ = accept (listener, NULL, NULL); // Send/receive large chunk to work around TCP slow start // This code is a workaround for #1608 if (*r_ != INVALID_SOCKET) { size_t dummy_size = 1024 * 1024; // 1M to overload default receive buffer unsigned char *dummy = static_cast<unsigned char *> (malloc (dummy_size)); wsa_assert (dummy); int still_to_send = static_cast<int> (dummy_size); int still_to_recv = static_cast<int> (dummy_size); while (still_to_send || still_to_recv) { int nbytes; if (still_to_send > 0) { nbytes = ::send ( *w_, reinterpret_cast<char *> (dummy + dummy_size - still_to_send), still_to_send, 0); wsa_assert (nbytes != SOCKET_ERROR); still_to_send -= nbytes; } nbytes = ::recv ( *r_, reinterpret_cast<char *> (dummy + dummy_size - still_to_recv), still_to_recv, 0); wsa_assert (nbytes != SOCKET_ERROR); still_to_recv -= nbytes; } free (dummy); } // Save errno if error occurred in bind/listen/connect/accept. int saved_errno = 0; if (*r_ == INVALID_SOCKET) saved_errno = WSAGetLastError (); // We don't need the listening socket anymore. Close it. rc = closesocket (listener); wsa_assert (rc != SOCKET_ERROR); if (sync != NULL) { // Exit the critical section. BOOL brc; if (signaler_port == event_signaler_port) brc = SetEvent (sync); else brc = ReleaseMutex (sync); win_assert (brc != 0); // Release the kernel object brc = CloseHandle (sync); win_assert (brc != 0); } if (*r_ != INVALID_SOCKET) { make_socket_noninheritable (*r_); return 0; } // Cleanup writer if connection failed if (*w_ != INVALID_SOCKET) { rc = closesocket (*w_); wsa_assert (rc != SOCKET_ERROR); *w_ = INVALID_SOCKET; } // Set errno from saved value errno = wsa_error_to_errno (saved_errno); return -1; #elif defined ZMQ_HAVE_OPENVMS // Whilst OpenVMS supports socketpair - it maps to AF_INET only. Further, // it does not set the socket options TCP_NODELAY and TCP_NODELACK which // can lead to performance problems. // // The bug will be fixed in V5.6 ECO4 and beyond. In the meantime, we'll // create the socket pair manually. struct sockaddr_in lcladdr; memset (&lcladdr, 0, sizeof lcladdr); lcladdr.sin_family = AF_INET; lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); lcladdr.sin_port = 0; int listener = open_socket (AF_INET, SOCK_STREAM, 0); errno_assert (listener != -1); int on = 1; int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on); errno_assert (rc != -1); rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELACK, &on, sizeof on); errno_assert (rc != -1); rc = bind (listener, (struct sockaddr *) &lcladdr, sizeof lcladdr); errno_assert (rc != -1); socklen_t lcladdr_len = sizeof lcladdr; rc = getsockname (listener, (struct sockaddr *) &lcladdr, &lcladdr_len); errno_assert (rc != -1); rc = listen (listener, 1); errno_assert (rc != -1); *w_ = open_socket (AF_INET, SOCK_STREAM, 0); errno_assert (*w_ != -1); rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on); errno_assert (rc != -1); rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELACK, &on, sizeof on); errno_assert (rc != -1); rc = connect (*w_, (struct sockaddr *) &lcladdr, sizeof lcladdr); errno_assert (rc != -1); *r_ = accept (listener, NULL, NULL); errno_assert (*r_ != -1); close (listener); return 0; #elif defined ZMQ_HAVE_VXWORKS struct sockaddr_in lcladdr; memset (&lcladdr, 0, sizeof lcladdr); lcladdr.sin_family = AF_INET; lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); lcladdr.sin_port = 0; int listener = open_socket (AF_INET, SOCK_STREAM, 0); errno_assert (listener != -1); int on = 1; int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof on); errno_assert (rc != -1); rc = bind (listener, (struct sockaddr *) &lcladdr, sizeof lcladdr); errno_assert (rc != -1); socklen_t lcladdr_len = sizeof lcladdr; rc = getsockname (listener, (struct sockaddr *) &lcladdr, (int *) &lcladdr_len); errno_assert (rc != -1); rc = listen (listener, 1); errno_assert (rc != -1); *w_ = open_socket (AF_INET, SOCK_STREAM, 0); errno_assert (*w_ != -1); rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof on); errno_assert (rc != -1); rc = connect (*w_, (struct sockaddr *) &lcladdr, sizeof lcladdr); errno_assert (rc != -1); *r_ = accept (listener, NULL, NULL); errno_assert (*r_ != -1); close (listener); return 0; #else // All other implementations support socketpair() int sv[2]; int type = SOCK_STREAM; // Setting this option result in sane behaviour when exec() functions // are used. Old sockets are closed and don't block TCP ports, avoid // leaks, etc. #if defined ZMQ_HAVE_SOCK_CLOEXEC type |= SOCK_CLOEXEC; #endif int rc = socketpair (AF_UNIX, type, 0, sv); if (rc == -1) { errno_assert (errno == ENFILE || errno == EMFILE); *w_ = *r_ = -1; return -1; } else { make_socket_noninheritable (sv[0]); make_socket_noninheritable (sv[1]); *w_ = sv[0]; *r_ = sv[1]; return 0; } #endif }
static int socket_error(void) { switch (WSAGetLastError()) { case 0: return 0; case WSAEINTR: return EINTR; case WSAEINVAL: return EINVAL; case WSA_INVALID_HANDLE: return EBADF; case WSA_NOT_ENOUGH_MEMORY: return ENOMEM; case WSA_INVALID_PARAMETER: return EINVAL; case WSAENAMETOOLONG: return ENAMETOOLONG; case WSAENOTEMPTY: return ENOTEMPTY; case WSAEWOULDBLOCK: /* not using EWOULDBLOCK as we don't want code to have * to check both EWOULDBLOCK and EAGAIN */ return EAGAIN; case WSAEINPROGRESS: return EINPROGRESS; case WSAEALREADY: return EALREADY; case WSAENOTSOCK: return ENOTSOCK; case WSAEDESTADDRREQ: return EDESTADDRREQ; case WSAEMSGSIZE: return EMSGSIZE; case WSAEPROTOTYPE: return EPROTOTYPE; case WSAENOPROTOOPT: return ENOPROTOOPT; case WSAEPROTONOSUPPORT: return EPROTONOSUPPORT; case WSAEOPNOTSUPP: return EOPNOTSUPP; case WSAEAFNOSUPPORT: return EAFNOSUPPORT; case WSAEADDRINUSE: return EADDRINUSE; case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL; case WSAENETDOWN: return ENETDOWN; case WSAENETUNREACH: return ENETUNREACH; case WSAENETRESET: return ENETRESET; case WSAECONNABORTED: return ECONNABORTED; case WSAECONNRESET: return ECONNRESET; case WSAENOBUFS: return ENOBUFS; case WSAEISCONN: return EISCONN; case WSAENOTCONN: return ENOTCONN; case WSAETIMEDOUT: return ETIMEDOUT; case WSAECONNREFUSED: return ECONNREFUSED; case WSAELOOP: return ELOOP; case WSAEHOSTUNREACH: return EHOSTUNREACH; default: return EIO; } }
/* Connect to SERVER at PORT and return a file descriptor or -1 on error. */ static int connect_server (const char *server, unsigned short port) { int sock = -1; #ifdef _WIN32 struct hostent *hp; struct sockaddr_in addr; unsigned long l; init_sockets (); memset (&addr, 0, sizeof addr); addr.sin_family = AF_INET; addr.sin_port = htons (port); /* Win32 gethostbyname doesn't handle IP addresses internally, so we try inet_addr first on that platform only. */ if ((l = inet_addr (server)) != INADDR_NONE) memcpy (&addr.sin_addr, &l, sizeof l); else if ((hp = gethostbyname (server))) { if (hp->h_addrtype != AF_INET) { fprintf (console, "gpgkeys: unknown address family for `%s'\n", server); return -1; } if (hp->h_length != 4) { fprintf (console, "gpgkeys: illegal address length for `%s'\n", server); return -1; } memcpy (&addr.sin_addr, hp->h_addr, hp->h_length); } else { fprintf (console, "gpgkeys: host `%s' not found: ec=%d\n", server, (int)WSAGetLastError ()); return -1; } sock = socket (AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { fprintf (console, "gpgkeys: error creating socket: ec=%d\n", (int)WSAGetLastError ()); return -1; } if (connect (sock, (struct sockaddr *)&addr, sizeof addr)) { fprintf (console, "gpgkeys: error connecting `%s': ec=%d\n", server, (int)WSAGetLastError ()); sock_close (sock); return -1; } #else struct sockaddr_in addr; struct hostent *host; addr.sin_family = AF_INET; addr.sin_port = htons (port); host = gethostbyname ((char*)server); if (!host) { fprintf (console, "gpgkeys: host `%s' not found: %s\n", server, strerror (errno)); return -1; } addr.sin_addr = *(struct in_addr*)host->h_addr; sock = socket (AF_INET, SOCK_STREAM, 0); if (sock == -1) { fprintf (console, "gpgkeys: error creating socket: %s\n", strerror (errno)); return -1; } if (connect (sock, (struct sockaddr *)&addr, sizeof addr) == -1) { fprintf (console, "gpgkeys: error connecting `%s': %s\n", server, strerror (errno)); close (sock); return -1; } #endif return sock; }
Pinger::Pinger() { // udp start sockaddr_in sa; // for UDP and raw sockets // ICMP must accept all responses sa.sin_family = AF_INET; sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = 0; udpStarted = false; // attempt to initialize raw ICMP socket is = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (is != INVALID_SOCKET) { int nRet = bind(is, (sockaddr *)&sa, sizeof(sa)); if (nRet==SOCKET_ERROR) { nRet = WSAGetLastError(); closesocket(is); // ignore return value - error close anyway } else { // attempt to initialize ordinal UDP socket - why should this fail??? // NB! no need to bind this at a moment - will be bound later, implicitly at sendto us = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (us == INVALID_SOCKET) { closesocket(is); // ignore return value - we need to close it anyway! } else { udpStarted = true; } } } // udp end // Open ICMP.DLL hICMP_DLL = LoadLibrary(_T("ICMP.DLL")); if (hICMP_DLL == 0) { theApp.QueueDebugLogLine(false,_T("Pinger: LoadLibrary() failed: Unable to locate ICMP.DLL!")); return; } // Get pointers to ICMP.DLL functions lpfnIcmpCreateFile = (IcmpCreateFile*)GetProcAddress(hICMP_DLL,"IcmpCreateFile"); lpfnIcmpCloseHandle = (IcmpCloseHandle*)GetProcAddress(hICMP_DLL,"IcmpCloseHandle"); lpfnIcmpSendEcho = (IcmpSendEcho*)GetProcAddress(hICMP_DLL,"IcmpSendEcho"); if ((!lpfnIcmpCreateFile) || (!lpfnIcmpCloseHandle) || (!lpfnIcmpSendEcho)) { theApp.QueueDebugLogLine(false,_T("Pinger: GetProcAddr() failed for at least one function.")); return; } // Open the ping service hICMP = (HANDLE) lpfnIcmpCreateFile(); if (hICMP == INVALID_HANDLE_VALUE) { int nErr = GetLastError(); theApp.QueueDebugLogLine(false, _T("Pinger: IcmpCreateFile() failed, err: %u"), nErr); PIcmpErr(nErr); return; } // Init IPInfo structure stIPInfo.Tos = 0; stIPInfo.Flags = 0; stIPInfo.OptionsSize = 0; stIPInfo.OptionsData = NULL; }
INT SOCKET_SOCKET_CLASS::readBinary(BYTE *buffer_ptr, UINT length) // DESCRIPTION : Read data from socket to given buffer. // PRECONDITIONS : // POSTCONDITIONS : // EXCEPTIONS : // NOTES : Blocks until all of the requested data is read or a timeout occurs. //<<=========================================================================== { struct fd_set fds; struct timeval tv = {socketTimeoutM, 0}; UINT read_bytes = 0; // number of bytes read from the socket if (loggerM_ptr) { loggerM_ptr->text(LOG_DEBUG, 1, "TCP/IP - socket::read(%d)", length); } if (!connectedM) { if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "TCP/IP - Not connected to peer - can't read data"); } return -1; } FD_ZERO(&fds); FD_SET(socketFdM, &fds); while (read_bytes < length) { int sel; // wait for something to read sel = select(socketFdM + 1, &fds, NULL, NULL, &tv); if (sel == 1) { INT rv = recv(socketFdM, (char *)(buffer_ptr + read_bytes), (length - read_bytes), 0); if (rv > 0) { // read some data read_bytes += rv; } else if (rv == 0) { // socket closed if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "TCP/IP - Socket closed during socket read"); } return -1; } else if (rv == SOCKET_ERROR) { // read error if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "TCP/IP - Socket read error (error code %d)", WSAGetLastError()); } return -1; } else { // unknown read error if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "TCP/IP - Unkown socket read error (read returned %d)", rv); } return -1; } } else if (sel == 0) { // no data at the end of the timeout if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 2, "TCP/IP - Connection timed-out while waiting to receive data"); return -1; } } else if (sel == SOCKET_ERROR) { // socket error if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 2, "TCP/IP - Error waiting to receive data (error code %d)", WSAGetLastError()); return -1; } } else { // unknown error if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 2, "TCP/IP - Unkown error while waiting to receive data (select returned %d)", sel); return -1; } } } return read_bytes; }
PingStatus Pinger::PingUDP(uint32 lAddr, uint32 ttl, bool doLog) { // UDPing reworked ping sequence --> int nTTL = ttl; int nRet; sockaddr_in sa; int nAddrLen = sizeof(struct sockaddr_in); char bufICMP[1500]; // allow full MTU // clear ICMP socket before sending UDP - not best solution, but may be needed to exclude late responses etc u_long bytes2read = 0; do { nRet = ioctlsocket(is, FIONREAD, &bytes2read); if (bytes2read > 0) { // ignore errors here sa.sin_family = AF_INET; sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = 0; nRet = recvfrom (is, /* socket */ (LPSTR)bufICMP, /* buffer */ 1500, /* length */ 0, /* flags */ (sockaddr*)&sa, /* source */ &nAddrLen); /* addrlen*/ //if (lastTimeOut) lastTimeOut--; //if (!lastTimeOut && toNowTimeOut) { // toNowTimeOut--; // if (toNowTimeOut) lastTimeOut = 3; //} } } while (bytes2read > 0); // set TTL value for UDP packet - should success with winsock 2 // NB! take care about IP_TTL value - it's redefined in Ws2tcpip.h! // TODO: solve next problem correctly: // eMule is linking sockets functions using wsock32.lib (IP_TTL=7) // to use IP_TTL define, we must enforce linker to bind this function // to ws2_32.lib (IP_TTL=4) (linker options: ignore wsock32.lib) nRet = setsockopt(us, IPPROTO_IP, IP_TTL, (char*)&nTTL, sizeof(int)); if (nRet==SOCKET_ERROR) { DWORD lastError = WSAGetLastError(); PingStatus returnValue; returnValue.success = false; returnValue.delay = TIMEOUT; returnValue.error = lastError; //if (toNowTimeOut < 3) toNowTimeOut++; // lastTimeOut = 3; return returnValue; } sa.sin_family = AF_INET; sa.sin_addr.s_addr = lAddr; sa.sin_port = htons(UDP_PORT); // send lonely UDP packet with almost minimal content (0 bytes is allowed too, but no data will be sent then) nRet = sendto(us, (LPSTR)&nTTL, 4, 0, (sockaddr*)&sa, sizeof(sa)); // send four bytes - TTL :) CTimeTick m_time; m_time.Tick(); if (nRet==SOCKET_ERROR) { DWORD lastError = WSAGetLastError(); PingStatus returnValue; returnValue.success = false; returnValue.error = lastError; //if (toNowTimeOut < 3) toNowTimeOut++; // lastTimeOut = 3; return returnValue; } IPHeader* reply = (IPHeader*)bufICMP; bytes2read = 0; int timeoutOpt = TIMEOUT; bool noRcvTimeOut = false; nRet = setsockopt(is, SOL_SOCKET, SO_RCVTIMEO, (const char*) &timeoutOpt, sizeof(timeoutOpt)); if (nRet==SOCKET_ERROR) noRcvTimeOut = true; float usResTime = 0.0f; while((usResTime += m_time.Tick()) < TIMEOUT){ if (noRcvTimeOut){ nRet = ioctlsocket(is, FIONREAD, &bytes2read); if (nRet != 0) { DWORD lastError = WSAGetLastError(); PingStatus returnValue; returnValue.success = false; returnValue.delay = TIMEOUT; returnValue.error = lastError; //if (toNowTimeOut < 3) toNowTimeOut++; // lastTimeOut = 3; return returnValue; } if (bytes2read > 0) { // read and filter incoming ICMP } else { Sleep(1); // share time with other threads continue; } } sa.sin_family = AF_INET; sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = 0; nRet = recvfrom (is, /* socket */ (LPSTR)bufICMP, /* buffer */ 1500, /* length */ 0, /* flags */ (sockaddr*)&sa, /* source */ &nAddrLen); /* addrlen*/ usResTime += m_time.Tick(); if (nRet==SOCKET_ERROR) { DWORD lastError = WSAGetLastError(); PingStatus returnValue; returnValue.success = false; returnValue.delay = TIMEOUT; returnValue.error = lastError; //if (toNowTimeOut < 3) toNowTimeOut++; // lastTimeOut = 3; return returnValue; } unsigned short header_len = reply->h_len * 4; ICMPHeader* icmphdr = (ICMPHeader*)(bufICMP + header_len); IN_ADDR stDestAddr; stDestAddr.s_addr = reply->source_ip; if (((icmphdr->type == ICMP_TTL_EXPIRE) || (icmphdr->type == ICMP_DEST_UNREACH)) && (icmphdr->UDP.dest_port == htons(UDP_PORT)) && (icmphdr->hdrsent.dest_ip == lAddr)) { PingStatus returnValue; if(icmphdr->type == ICMP_TTL_EXPIRE) { returnValue.success = true; returnValue.status = IP_TTL_EXPIRED_TRANSIT; returnValue.delay = usResTime; returnValue.destinationAddress = stDestAddr.s_addr; returnValue.ttl = ttl; } else { returnValue.success = true; returnValue.status = IP_DEST_HOST_UNREACHABLE; returnValue.delay = usResTime; returnValue.destinationAddress = stDestAddr.s_addr; returnValue.ttl = 64 - (reply->ttl & 63); } if(doLog) { theApp.QueueDebugLogLine(false,_T("Reply (UDP-pinger) from %s: bytes=%d time=%3.2fms TTL=%i"), ipstr(stDestAddr), nRet, usResTime, returnValue.ttl); } return returnValue; } else { // verbose log filtered packets info (not seen yet...) //if (lastTimeOut) lastTimeOut--; //if (!lastTimeOut && toNowTimeOut) { // toNowTimeOut--; // if (toNowTimeOut) lastTimeOut = 3; //} if(doLog) { theApp.QueueDebugLogLine(false,_T("Filtered reply (UDP-pinger) from %s: bytes=%d time=%3.2fms TTL=%i type=%i"), ipstr(stDestAddr), nRet, usResTime, 64 - (reply->ttl & 63), icmphdr->type); } } } //if (usResTime >= TIMEOUT) { // if (toNowTimeOut < 3) toNowTimeOut++; // lastTimeOut = 3; //} // UDPing reworked ping sequence end <-- PingStatus returnValue; returnValue.success = false; returnValue.delay = TIMEOUT; returnValue.error = IP_REQ_TIMED_OUT; return returnValue; }
/****** C_Communication::DoComm() const **************************************** * NAME * C_Communication::DoComm() const -- does the communication * * SYNOPSIS * int C_Communication::DoComm() const * * FUNCTION * Does the communication with sge_shepherd. I.e. whenever a sge_shepherd * connects to the server, it receives the request, does what is requested * and then shuts down the connection. * * RESULT * int - 0 if command was successfully received and processed, 1 else * * NOTES *******************************************************************************/ int C_Communication::DoComm() const { int ret = 1; int idx = 0; SOCKET comm_sock; int remote_saddr_len; struct sockaddr_in remote_saddr; char szMessage[1024]; char command[COMMAND_SIZE]; const int commandsize = sizeof(command); C_Job Job; C_Job *pJob = NULL; en_request_type request_type; remote_saddr_len = sizeof(remote_saddr); comm_sock = accept(m_ListenSocket, (struct sockaddr*)&remote_saddr, &remote_saddr_len); if(comm_sock == INVALID_SOCKET) { return WSAGetLastError(); } ZeroMemory(command, COMMAND_SIZE); while((ret=recv(comm_sock, command+idx, commandsize-idx, 0))>0) { idx += ret; if(command[idx-1] == EOF) { break; } } if(ret == -1) { ret = WSAGetLastError(); ShutdownSocket(&comm_sock); return ret; } ret = 0; WriteToLogFile("Received new request, will parse it now."); request_type = Job.ParseCommand(command); WriteToLogFile("Finished parsing the new request."); switch(request_type) { case req_job_start: { BOOL bAlreadyInList = TRUE; HANDLE hThread; WriteToLogFile("Got a job start request."); if(g_bAcceptJobs) { Job.m_comm_sock = comm_sock; sprintf(szMessage, "Starting job %lu.%lu %s", Job.m_job_id, Job.m_ja_task_id, Job.m_pe_task_id ? Job.m_pe_task_id : "<null>"); WriteToLogFile(szMessage); // try to put job in job list pJob = new C_Job(Job); bAlreadyInList = g_JobList.AddJobToList(pJob); } if (bAlreadyInList == FALSE) { WriteToLogFile("New job, starting thread"); // job is not already in job list, send ACK and start worker thread hThread = CreateThread(NULL, 0, JobStarterThread, 0, 0, 0); CloseHandle(hThread); } else { WriteToLogFile("Existing job, send NACK and delete job object"); // job is already in job list, send NACK and delete job object strcpy(szMessage, "NAK"); szMessage[strlen(szMessage)+1] = (char)EOF; send(comm_sock, szMessage, (int)strlen(szMessage)+2, 0); ShutdownSocket(&comm_sock); delete pJob; pJob = NULL; } } break; case req_send_job_usage: WriteToLogFile("Got a send usage request."); pJob = g_JobList.RemoveJobFromList(Job); if(pJob) { pJob->m_comm_sock = comm_sock; SendJobUsage(*pJob); delete pJob; pJob = NULL; sprintf(szMessage, "Sending usage of job %lu.%lu %s", Job.m_job_id, Job.m_ja_task_id, Job.m_pe_task_id ? Job.m_pe_task_id : "<null>"); } else { sprintf(szMessage, "Warning: Job %lu.%lu %s not found!", Job.m_job_id, Job.m_ja_task_id, Job.m_pe_task_id ? Job.m_pe_task_id : "<null>"); } WriteToLogFile(szMessage); ShutdownSocket(&comm_sock); break; case req_forward_signal: WriteToLogFile("Got a forward signal request."); // lock access to job list WaitForSingleObject(g_JobList.m_hJobListMutex, INFINITE); pJob = g_JobList.FindJobInList(Job); if(pJob && pJob->m_JobStatus != js_Finished && pJob->m_JobStatus != js_Failed && pJob->m_JobStatus != js_Deleted) { BOOL bRet = FALSE; char szAnswer[100]; int sent; if(pJob->m_hProcess != INVALID_HANDLE_VALUE && pJob->m_hJobObject != INVALID_HANDLE_VALUE) { bRet = TerminateJobObject(pJob->m_hJobObject, 0); if(bRet) { pJob->m_JobStatus = js_Deleted; } } ReleaseMutex(g_JobList.m_hJobListMutex); sprintf(szAnswer, "%s", bRet ? "ACK" : "NAK"); szAnswer[strlen(szAnswer)+1] = (char)EOF; sent = send(comm_sock, szAnswer, (int)strlen(szAnswer)+2, 0); if(sent >= 0) { ret = 0; } } else { ReleaseMutex(g_JobList.m_hJobListMutex); } ShutdownSocket(&comm_sock); break; } return ret; }
// Initialize the listener, set up the socket to listen on, or return an error CListener::ErrorType CListener::Initialize(int TCPSocket) { TCHAR MsgText[100]; CString TCPSocketText; TCPSocketText.Format(_T("%i"),TCPSocket); WSADATA wsadata; if (WSAStartup(MAKEWORD(2,0), &wsadata)) return UnknownError; // Get list of addresses to listen on ADDRINFOT Hints, *AddrInfo, *AI; memset(&Hints, 0, sizeof (Hints)); Hints.ai_family = PF_UNSPEC; Hints.ai_socktype = SOCK_STREAM; Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE; if (GetAddrInfo(NULL, TCPSocketText, &Hints, &AddrInfo) != 0) { StringCchPrintf(MsgText, _countof(MsgText), _T("getaddressinfo error: %i"), GetLastError()); LogWarning(MsgText); return UnknownError; } // Create one or more passive sockets to listen on int i; for (i = 0, AI = AddrInfo; AI != NULL; AI = AI->ai_next) { // Did we receive more addresses than we can handle? Highly unlikely, but check anyway. if (i == FD_SETSIZE) break; // Only support PF_INET and PF_INET6. If something else, skip to next address. if ((AI->ai_family != AF_INET) && (AI->ai_family != AF_INET6)) continue; // StringCchPrintf(MsgText, _countof(MsgText), _T("::OnInit i = %d, ai_family = %d"), i, AI->ai_family); // LogWarning(MsgText); m_hSocketEvents[i] = CreateEvent( NULL, // no security attributes true, // manual reset event false, // not signaled NULL); // no name if (!(m_hSocketEvents[i])) return UnknownError; // StringCchPrintf(MsgText, _countof(MsgText), _T("::OnInit Created m_hSocketEvents[%d], handle=%d"), i, m_hSocketEvents[i]); // LogWarning(MsgText); m_iListenSockets[i] = WSASocket(AI->ai_family, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); if (m_iListenSockets[i] == INVALID_SOCKET) return SocketUnusable; // StringCchPrintf(MsgText, _countof(MsgText), _T("::OnInit binding m_iListenSockets[%d] to sa_family=%u sa_data=%s len=%d"), i, AI->ai_addr->sa_family, AI->ai_addr->sa_data, AI->ai_addrlen); // LogWarning(MsgText); int rc = bind(m_iListenSockets[i], AI->ai_addr, (int)AI->ai_addrlen); if (rc) { if (WSAGetLastError()==WSAEADDRINUSE) return SocketInuse; else return SocketUnusable; } if (listen(m_iListenSockets[i], 10)) return SocketUnusable; if (WSAEventSelect(m_iListenSockets[i], m_hSocketEvents[i], FD_ACCEPT)) return SocketUnusable; i++; } m_iNumListenSockets = i; // StringCchPrintf(MsgText, _countof(MsgText), _T("::OnInit no errors, m_iNumListenSockets = %d"), m_iNumListenSockets); // LogWarning(MsgText); return NoError; }
int _getdns_handle_select(struct _getdns_event_base* base, struct timeval* wait) { DWORD timeout = 0; /* in milliseconds */ DWORD ret; WSANETWORKEVENTS netev; struct _getdns_event* eventlist[WSK_MAX_ITEMS]; int i, numwait = 0, startidx = 0, was_timeout = 0; int newstickies = 0; struct timeval nultm; printf("in handle select\n"); #ifndef S_SPLINT_S if(wait->tv_sec==(time_t)-1) wait = NULL; if (wait) // timeout = 10 + wait->tv_usec / 1000; timeout = wait->tv_sec * 1000 + wait->tv_usec / 1000; if(base->tcp_stickies) { wait = &nultm; nultm.tv_sec = 0; nultm.tv_usec = 0; timeout = 0; /* no waiting, we have sticky events */ } #endif /* prepare event array */ for(i=0; i<base->max; i++) { if(base->items[i]->ev_fd == -1 && !base->items[i]->is_signal) continue; /* skip timer only events */ eventlist[numwait] = base->items[i]; base->waitfor[numwait++] = base->items[i]->hEvent; printf("winsock_event bmax=%d numwait=%d wait=%x " "timeout=%d hEvent %d\n", base->max, numwait, (int)wait, (int)timeout, base->items[i]->hEvent); if (numwait == WSK_MAX_ITEMS) break; /* sanity check */ } //log_assert(numwait <= WSA_MAXIMUM_WAIT_EVENTS); /* do the wait */ if(numwait == 0) { /* WSAWaitFor.. doesn't like 0 event objects */ if(wait) { Sleep(timeout); } was_timeout = 1; } else { //g do not sched udp write for (i = 0; i<base->max; i++) { if (!base->items[i]->is_tcp && base->items[i]->ev_events&EV_WRITE) { //gprintf("skip UDP sched\n"); (*eventlist[i]->ev_callback)(eventlist[i]->ev_fd, EV_WRITE & eventlist[i]->ev_events, eventlist[i]->ev_arg); return 0; } } //gprintf("before wait %d\n", base->items[0]->ev_events); ret = WSAWaitForMultipleEvents(numwait, base->waitfor, 0 /* do not wait for all, just one will do */, wait?timeout:WSA_INFINITE, 0); /* we are not alertable (IO completion events) */ //gprintf("after wait %d %d\n", ret, numwait); if(ret == WSA_WAIT_IO_COMPLETION) { //printf("getdns: WSAWaitForMultipleEvents failed: WSA_WAIT_IO_COMPLETION"); return -1; } else if(ret == WSA_WAIT_FAILED) { //printf("getdns: WSAWaitForMultipleEvents failed: %s", // wsa_strerror(WSAGetLastError())); return -1; } else if(ret == WSA_WAIT_TIMEOUT) { //printf("timeout\n"); was_timeout = 1; } else startidx = ret - WSA_WAIT_EVENT_0; } ////verbose(VERB_CLIENT, "winsock_event wake was_timeout=%d startidx=%d", // was_timeout, startidx); /* get new time after wait */ if(settime(base) < 0) return -1; /* callbacks */ if(base->tcp_stickies) startidx = 0; /* process all events, some are sticky */ for(i=startidx; i<numwait; i++) eventlist[i]->just_checked = 1; //verbose(VERB_CLIENT, "winsock_event signals"); for(i=startidx; i<numwait; i++) { if(!base->waitfor[i]) continue; /* was deleted */ if(eventlist[i]->is_signal) { eventlist[i]->just_checked = 0; _getdns_handle_signal(eventlist[i]); } } /* early exit - do not process network, exit quickly */ if(base->need_to_exit) return 0; //verbose(VERB_CLIENT, "winsock_event net"); for(i=startidx; i<numwait; i++) { short bits = 0; /* eventlist[i] fired */ /* see if eventlist[i] is still valid and just checked from * WSAWaitForEvents */ if(!base->waitfor[i]) continue; /* was deleted */ if(!eventlist[i]->just_checked) continue; /* added by other callback */ if(eventlist[i]->is_signal) continue; /* not a network event at all */ eventlist[i]->just_checked = 0; if(WSAEnumNetworkEvents(eventlist[i]->ev_fd, base->waitfor[i], /* reset the event handle */ /*NULL,*/ /* do not reset the event handle */ &netev) != 0) { log_err("getdns: WSAEnumNetworkEvents failed: %s", wsa_strerror(WSAGetLastError())); return -1; } if((netev.lNetworkEvents & FD_READ)) { if(netev.iErrorCode[FD_READ_BIT] != 0) printf("FD_READ_BIT error: %s\n", wsa_strerror(netev.iErrorCode[FD_READ_BIT])); bits |= EV_READ; printf("FD_READ_BIT\n"); } if((netev.lNetworkEvents & FD_WRITE)) { if(netev.iErrorCode[FD_WRITE_BIT] != 0) printf("FD_WRITE_BIT error: %s\n", wsa_strerror(netev.iErrorCode[FD_WRITE_BIT])); bits |= EV_WRITE; printf("FD_WRITE_BIT\n"); } if((netev.lNetworkEvents & FD_CONNECT)) { if(netev.iErrorCode[FD_CONNECT_BIT] != 0) printf("FD_CONNECT_BIT error: %s\n", wsa_strerror(netev.iErrorCode[FD_CONNECT_BIT])); bits |= EV_READ; bits |= EV_WRITE; printf("FD_CONNECT_BIT\n"); } if((netev.lNetworkEvents & FD_ACCEPT)) { if(netev.iErrorCode[FD_ACCEPT_BIT] != 0) printf("FD_ACCEPT_BIT error: %s\n", wsa_strerror(netev.iErrorCode[FD_ACCEPT_BIT])); bits |= EV_READ; printf("FD_ACCEPT_BIT\n"); } if((netev.lNetworkEvents & FD_CLOSE)) { if(netev.iErrorCode[FD_CLOSE_BIT] != 0) printf("FD_CLOSE_BIT error: %s\n", wsa_strerror(netev.iErrorCode[FD_CLOSE_BIT])); bits |= EV_READ; bits |= EV_WRITE; printf("FD_CLOSE_BIT\n"); } if(eventlist[i]->is_tcp && eventlist[i]->stick_events) { /* printf("winsock %d pass sticky %s%s\n", eventlist[i]->ev_fd, (eventlist[i]->old_events&EV_READ)?"EV_READ":"", (eventlist[i]->old_events&EV_WRITE)?"EV_WRITE":""); */ bits |= eventlist[i]->old_events; } if(eventlist[i]->is_tcp && bits) { eventlist[i]->old_events = bits; eventlist[i]->stick_events = 1; if((eventlist[i]->ev_events & bits)) { newstickies = 1; } /* printf("winsock %d store sticky %s%s", eventlist[i]->ev_fd, (eventlist[i]->old_events&EV_READ)?"EV_READ":"", (eventlist[i]->old_events&EV_WRITE)?"EV_WRITE":""); */ } if((bits & eventlist[i]->ev_events)) { /* printf( "winsock event callback %p fd=%d " "%s%s%s%s%s ; %s%s%s\n", eventlist[i], eventlist[i]->ev_fd, (netev.lNetworkEvents&FD_READ)?" FD_READ":"", (netev.lNetworkEvents&FD_WRITE)?" FD_WRITE":"", (netev.lNetworkEvents&FD_CONNECT)? " FD_CONNECT":"", (netev.lNetworkEvents&FD_ACCEPT)? " FD_ACCEPT":"", (netev.lNetworkEvents&FD_CLOSE)?" FD_CLOSE":"", (bits&EV_READ)?" EV_READ":"", (bits&EV_WRITE)?" EV_WRITE":"", (bits&EV_TIMEOUT)?" EV_TIMEOUT":""); */ fptr_ok(fptr_whitelist_event( eventlist[i]->ev_callback)); (*eventlist[i]->ev_callback)(eventlist[i]->ev_fd, bits & eventlist[i]->ev_events, eventlist[i]->ev_arg); } /* if(eventlist[i]->is_tcp && bits) printf( "winsock %d got sticky %s%s\n", eventlist[i]->ev_fd, (eventlist[i]->old_events&EV_READ)?"EV_READ":"", (eventlist[i]->old_events&EV_WRITE)?"EV_WRITE":""); */ } //verbose(VERB_CLIENT, "winsock_event net"); if(base->tcp_reinvigorated) { printf("winsock_event reinvigorated\n"); base->tcp_reinvigorated = 0; newstickies = 1; } base->tcp_stickies = newstickies; //gprintf("winsock_event handle_select end\n"); return 0; }
/* * Class: java_net_DualStackPlainSocketImpl * Method: listen0 * Signature: (II)V */ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_listen0 (JNIEnv *env, jclass clazz, jint fd, jint backlog) { if (listen(fd, backlog) == SOCKET_ERROR) { NET_ThrowNew(env, WSAGetLastError(), "listen failed"); } }
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) { int err; unsigned int i; uv_tcp_accept_t* req; if (handle->flags & UV_HANDLE_CONNECTION && handle->shutdown_req != NULL && handle->write_reqs_pending == 0) { UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req); err = 0; if (handle->flags & UV__HANDLE_CLOSING) { err = ERROR_OPERATION_ABORTED; } else if (shutdown(handle->socket, SD_SEND) == SOCKET_ERROR) { err = WSAGetLastError(); } if (handle->shutdown_req->cb) { handle->shutdown_req->cb(handle->shutdown_req, uv_translate_sys_error(err)); } handle->shutdown_req = NULL; DECREASE_PENDING_REQ_COUNT(handle); return; } if (handle->flags & UV__HANDLE_CLOSING && handle->reqs_pending == 0) { assert(!(handle->flags & UV_HANDLE_CLOSED)); if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) { closesocket(handle->socket); handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; } if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->accept_reqs) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) { for (i = 0; i < uv_simultaneous_server_accepts; i++) { req = &handle->accept_reqs[i]; if (req->wait_handle != INVALID_HANDLE_VALUE) { UnregisterWait(req->wait_handle); req->wait_handle = INVALID_HANDLE_VALUE; } if (req->event_handle) { CloseHandle(req->event_handle); req->event_handle = NULL; } } } free(handle->accept_reqs); handle->accept_reqs = NULL; } if (handle->flags & UV_HANDLE_CONNECTION && handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { UnregisterWait(handle->read_req.wait_handle); handle->read_req.wait_handle = INVALID_HANDLE_VALUE; } if (handle->read_req.event_handle) { CloseHandle(handle->read_req.event_handle); handle->read_req.event_handle = NULL; } } uv__handle_close(handle); loop->active_tcp_streams--; } }
int main() { SOCKET wsocket; struct sockaddr_in server; struct sockaddr_in secondary_input; int slen; int recv_len; char _buffer[BUFLEN]; WSADATA wsa; slen = sizeof(secondary_input); // initialize socket printf("%s\n", "Initializing dear system sequence..."); if(WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { printf("%s%s\n", "ERR", "winsock failure initializing. Rejecting telemetry."); return WSAGetLastError(); } printf("%s", "Winsock initialized...\n"); // create socket if(wsocket = socket(AF_INET, SOCK_DGRAM, 0) == INVALID_SOCKET) { printf("%s%s\n", "ERR", "winsock failure spawning. Rejecting telemetry."); return WSAGetLastError(); } printf("%s", "Winsock spawned. Binding..."); // set struct properties server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(PORT); // bind socket if(bind(wsocket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) { printf("%s%s\n", "ERR", "winsock failure binding. Rejecting telemetry."); return WSAGetLastError(); } printf("%s", "winsock ready. Listening for telemetry...\n"); while(1) { fflush(stdout); memset(_buffer, '\0', BUFLEN); // receive data if((recv_len = recvfrom(wsocket, _buffer, BUFLEN, 0, (struct sockaddr *)&secondary_input, &slen)) == SOCKET_ERROR) { printf("%s\n", "winsock failure receiving telemetry. Flushing..."); return WSAGetLastError(); } // print data printf("%s\n", _buffer); } closesocket(wsocket); WSACleanup(); return 0; }
static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) { uv_loop_t* loop = handle->loop; BOOL success; DWORD bytes; SOCKET accept_socket; short family; assert(handle->flags & UV_HANDLE_LISTENING); assert(req->accept_socket == INVALID_SOCKET); /* choose family and extension function */ if (handle->flags & UV_HANDLE_IPV6) { family = AF_INET6; } else { family = AF_INET; } /* Open a socket for the accepted connection. */ accept_socket = socket(family, SOCK_STREAM, 0); if (accept_socket == INVALID_SOCKET) { SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; return; } /* Make the socket non-inheritable */ if (!SetHandleInformation((HANDLE) accept_socket, HANDLE_FLAG_INHERIT, 0)) { SET_REQ_ERROR(req, GetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; closesocket(accept_socket); return; } /* Prepare the overlapped structure. */ memset(&(req->overlapped), 0, sizeof(req->overlapped)); if (handle->flags & UV_HANDLE_EMULATE_IOCP) { req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); } success = handle->func_acceptex(handle->socket, accept_socket, (void*)req->accept_buffer, 0, sizeof(struct sockaddr_storage), sizeof(struct sockaddr_storage), &bytes, &req->overlapped); if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { /* Process the req without IOCP. */ req->accept_socket = accept_socket; handle->reqs_pending++; uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(success)) { /* The req will be processed with IOCP. */ req->accept_socket = accept_socket; handle->reqs_pending++; if (handle->flags & UV_HANDLE_EMULATE_IOCP && req->wait_handle == INVALID_HANDLE_VALUE && !RegisterWaitForSingleObject(&req->wait_handle, req->event_handle, post_completion, (void*) req, INFINITE, WT_EXECUTEINWAITTHREAD)) { SET_REQ_ERROR(req, GetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; return; } } else { /* Make this req pending reporting an error. */ SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; /* Destroy the preallocated client socket. */ closesocket(accept_socket); /* Destroy the event handle */ if (handle->flags & UV_HANDLE_EMULATE_IOCP) { CloseHandle(req->overlapped.hEvent); req->event_handle = NULL; } } }
int zmq::tcp_listener_t::set_address (const char *addr_) { // Convert the textual address into address structure. int rc = address.resolve (addr_, true, options.ipv4only ? true : false); if (rc != 0) return -1; // Create a listening socket. s = open_socket (address.family (), SOCK_STREAM, IPPROTO_TCP); #ifdef ZMQ_HAVE_WINDOWS if (s == INVALID_SOCKET) errno = wsa_error_to_errno (WSAGetLastError ()); #endif // IPv6 address family not supported, try automatic downgrade to IPv4. if (address.family () == AF_INET6 && errno == EAFNOSUPPORT && !options.ipv4only) { rc = address.resolve (addr_, true, true); if (rc != 0) return rc; s = ::socket (address.family (), SOCK_STREAM, IPPROTO_TCP); } #ifdef ZMQ_HAVE_WINDOWS if (s == INVALID_SOCKET) { errno = wsa_error_to_errno (WSAGetLastError ()); return -1; } // On Windows, preventing sockets to be inherited by child processes. BOOL brc = SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0); win_assert (brc); #else if (s == -1) return -1; #endif // On some systems, IPv4 mapping in IPv6 sockets is disabled by default. // Switch it on in such cases. if (address.family () == AF_INET6) enable_ipv4_mapping (s); // Allow reusing of the address. int flag = 1; #ifdef ZMQ_HAVE_WINDOWS rc = setsockopt (s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*) &flag, sizeof (int)); wsa_assert (rc != SOCKET_ERROR); #else rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int)); errno_assert (rc == 0); #endif address.to_string (endpoint); // Bind the socket to the network interface and port. rc = bind (s, address.addr (), address.addrlen ()); #ifdef ZMQ_HAVE_WINDOWS if (rc == SOCKET_ERROR) { errno = wsa_error_to_errno (WSAGetLastError ()); goto error; } #else if (rc != 0) goto error; #endif // Listen for incomming connections. rc = listen (s, options.backlog); #ifdef ZMQ_HAVE_WINDOWS if (rc == SOCKET_ERROR) { errno = wsa_error_to_errno (WSAGetLastError ()); goto error; } #else if (rc != 0) goto error; #endif socket->monitor_event (ZMQ_EVENT_LISTENING, addr_, s); return 0; error: int err = errno; close (); errno = err; return -1; }
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { uv_loop_t* loop = handle->loop; unsigned int i, simultaneous_accepts; uv_tcp_accept_t* req; int err; assert(backlog > 0); if (handle->flags & UV_HANDLE_LISTENING) { handle->connection_cb = cb; } if (handle->flags & UV_HANDLE_READING) { return WSAEISCONN; } if (handle->flags & UV_HANDLE_BIND_ERROR) { return handle->bind_error; } if (!(handle->flags & UV_HANDLE_BOUND)) { err = uv_tcp_try_bind(handle, (const struct sockaddr*) &uv_addr_ip4_any_, sizeof(uv_addr_ip4_any_), 0); if (err) return err; } if (!handle->func_acceptex) { if (!uv_get_acceptex_function(handle->socket, &handle->func_acceptex)) { return WSAEAFNOSUPPORT; } } if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) && listen(handle->socket, backlog) == SOCKET_ERROR) { return WSAGetLastError(); } handle->flags |= UV_HANDLE_LISTENING; handle->connection_cb = cb; INCREASE_ACTIVE_COUNT(loop, handle); simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1 : uv_simultaneous_server_accepts; if(!handle->accept_reqs) { handle->accept_reqs = (uv_tcp_accept_t*) malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t)); if (!handle->accept_reqs) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } for (i = 0; i < simultaneous_accepts; i++) { req = &handle->accept_reqs[i]; uv_req_init(loop, (uv_req_t*)req); req->type = UV_ACCEPT; req->accept_socket = INVALID_SOCKET; req->data = handle; req->wait_handle = INVALID_HANDLE_VALUE; if (handle->flags & UV_HANDLE_EMULATE_IOCP) { req->event_handle = CreateEvent(NULL, 0, 0, NULL); if (!req->event_handle) { uv_fatal_error(GetLastError(), "CreateEvent"); } } else { req->event_handle = NULL; } uv_tcp_queue_accept(handle, req); } /* Initialize other unused requests too, because uv_tcp_endgame */ /* doesn't know how how many requests were intialized, so it will */ /* try to clean up {uv_simultaneous_server_accepts} requests. */ for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) { req = &handle->accept_reqs[i]; uv_req_init(loop, (uv_req_t*) req); req->type = UV_ACCEPT; req->accept_socket = INVALID_SOCKET; req->data = handle; req->wait_handle = INVALID_HANDLE_VALUE; req->event_handle = NULL; } } return 0; }
void zmq::udp_engine_t::in_event() { struct sockaddr_in in_address; socklen_t in_addrlen = sizeof(sockaddr_in); #ifdef ZMQ_HAVE_WINDOWS int nbytes = recvfrom(fd, (char*) in_buffer, MAX_UDP_MSG, 0, (sockaddr*) &in_address, &in_addrlen); const int last_error = WSAGetLastError(); if (nbytes == SOCKET_ERROR) { wsa_assert( last_error == WSAENETDOWN || last_error == WSAENETRESET || last_error == WSAEWOULDBLOCK); return; } #else int nbytes = recvfrom(fd, in_buffer, MAX_UDP_MSG, 0, (sockaddr*) &in_address, &in_addrlen); if (nbytes == -1) { errno_assert(errno != EBADF && errno != EFAULT && errno != ENOMEM && errno != ENOTSOCK); return; } #endif int rc; int body_size; int body_offset; msg_t msg; if (options.raw_socket) { sockaddr_to_msg (&msg, &in_address); body_size = nbytes; body_offset = 0; } else { char* group_buffer = (char *)in_buffer + 1; int group_size = in_buffer[0]; rc = msg.init_size (group_size); errno_assert (rc == 0); msg.set_flags (msg_t::more); memcpy (msg.data (), group_buffer, group_size); // This doesn't fit, just ingore if (nbytes - 1 < group_size) return; body_size = nbytes - 1 - group_size; body_offset = 1 + group_size; } rc = session->push_msg (&msg); errno_assert (rc == 0 || (rc == -1 && errno == EAGAIN)); // Pipe is full if (rc != 0) { rc = msg.close (); errno_assert (rc == 0); reset_pollin (handle); return; } rc = msg.close (); errno_assert (rc == 0); rc = msg.init_size (body_size); errno_assert (rc == 0); memcpy (msg.data (), in_buffer + body_offset, body_size); rc = session->push_msg (&msg); errno_assert (rc == 0); rc = msg.close (); errno_assert (rc == 0); session->flush (); }
int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb) { int result; DWORD bytes; uv_req_init(loop, (uv_req_t*) req); req->type = UV_WRITE; req->handle = (uv_stream_t*) handle; req->cb = cb; /* Prepare the overlapped structure. */ memset(&(req->overlapped), 0, sizeof(req->overlapped)); if (handle->flags & UV_HANDLE_EMULATE_IOCP) { req->event_handle = CreateEvent(NULL, 0, 0, NULL); if (!req->event_handle) { uv_fatal_error(GetLastError(), "CreateEvent"); } req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); req->wait_handle = INVALID_HANDLE_VALUE; } result = WSASend(handle->socket, (WSABUF*) bufs, nbufs, &bytes, 0, &req->overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Request completed immediately. */ req->queued_bytes = 0; handle->reqs_pending++; handle->write_reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); uv_insert_pending_req(loop, (uv_req_t*) req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* Request queued by the kernel. */ req->queued_bytes = uv_count_bufs(bufs, nbufs); handle->reqs_pending++; handle->write_reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); handle->write_queue_size += req->queued_bytes; if (handle->flags & UV_HANDLE_EMULATE_IOCP && !RegisterWaitForSingleObject(&req->wait_handle, req->event_handle, post_write_completion, (void*) req, INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { SET_REQ_ERROR(req, GetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); } } else { /* Send failed due to an error. */ return WSAGetLastError(); } return 0; }
CString CHttpReqSocket::GetHTTPContent(CString strHost, CString strRequest, bool* pbCancelDownload, int& nError, int nApproxContentLength, CProgressCtrl *pProgress, CWnd* pStatus, CString strFilename) { // init sockets AfxSocketInit (); CHttpReqSocket socket; nError = 0; // try to create the socket if (!socket.Create ()) { nError = WSAGetLastError (); return ""; } // try to connect to server if (!socket.Connect (strHost, 80)) { nError = socket.GetLastError (); socket.Close (); return ""; } // wait for response socket.Send (strRequest, strRequest.GetLength ()); CString strRecv; char szBuf[4096 + 1]; int nPos, nContLen = -1; int nLen = 0; // create and open file, if stream is to be written to a file // (i.e. strFilename is not empty) CFile file; bool bUseFile = !strFilename.IsEmpty (); bool bHeaderRead = false; if (bUseFile) file.Open (strFilename, CFile::modeCreate | CFile::modeWrite); // init progress control if (pProgress != NULL) pProgress->SetRange32 (0, nApproxContentLength); MSG msg; CString strStatus; // read http stream for (int nRead = 1; nRead > 0; ) { if (*pbCancelDownload) break; // read from the socket nRead = socket.Receive (szBuf, 4096); switch (nRead) { case 0: continue; case SOCKET_ERROR: nError = socket.GetLastError (); break; default: if (bUseFile) { // write stream to file if (!bHeaderRead) { // try to get the Content-Length header char* pBuf = strstr (szBuf, "Content-Length:"); if (pBuf) nContLen = atoi (pBuf + 15); if (pProgress != NULL) pProgress->SetRange32 (0, nContLen); // cut off the header (should not be saved to the file) pBuf = strstr (szBuf, "\r\n\r\n"); int nHeaderLen = (int) (pBuf - szBuf); file.Write (pBuf + 4, nRead - nHeaderLen - 4); // file.Write (szBuf, nRead); // return the header LPSTR pRecvBuf = strRecv.GetBuffer (nHeaderLen); strncpy (pRecvBuf, szBuf, nHeaderLen); pRecvBuf[nHeaderLen] = '\0'; strRecv.ReleaseBuffer (); bHeaderRead = true; } else file.Write (szBuf, nRead); } else { // save stream as string to return szBuf[nRead] = '\0'; strRecv += szBuf; // try to get the Content-Length header // and set the progress control's range appropriately if (!bHeaderRead) { if ((nPos = strRecv.Find ("Content-Length:")) >= 0) { nContLen = atoi (strRecv.Mid (nPos + 15)); if (pProgress != NULL) pProgress->SetRange32 (0, nContLen); } bHeaderRead = true; } } } nLen += nRead; if (nContLen >= 0) if (nLen >= nContLen) nRead = 0; if (pProgress != NULL) pProgress->SetPos (nLen); if (pStatus != NULL) { strStatus.Format (IDS_DOWNLOADSTATUS, (double) nLen / 1024.0, (double) nContLen / 1024.0); pStatus->SetWindowText (strStatus); } while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage (&msg); } socket.Close (); if (bUseFile) file.Close (); return strRecv; }