예제 #1
0
파일: net_win32.c 프로젝트: ARMinARM/elua
net_ssize_t net_recvfrom( NET_SOCKET s, void *buf, size_t len, int flags, struct sockaddr* from, socklen_t *fromlen, int timeout )
{
  DWORD readbytes = 0;
  DWORD rflags = ( DWORD )flags;
  BOOL dwRes;
  DWORD selflags;
  WSABUF datadesc = { len, buf };
  
  ResetEvent( s->o.hEvent );
  if( WSARecvFrom( s->s, &datadesc, 1, &readbytes, &rflags, from, fromlen, &s->o, NULL ) == SOCKET_ERROR )
  {
    if( WSAGetLastError() != WSA_IO_PENDING )
      return 0;
  }
  else
    return readbytes;
  
  dwRes = WaitForSingleObject( s->o.hEvent, timeout == NET_INF_TIMEOUT ? INFINITE : timeout );
  if( dwRes == WAIT_OBJECT_0 ) 
  {
    if( !WSAGetOverlappedResult( s->s, &s->o, &readbytes, TRUE, &selflags ) )
      readbytes = 0;
  }
  else if( dwRes == WAIT_TIMEOUT )
  {
    WSAGetOverlappedResult( s->s, &s->o, &readbytes, TRUE, &selflags );
    readbytes = 0;
  }
  
  return readbytes;    
}
예제 #2
0
파일: io.c 프로젝트: hideman-ltd/peervpn
// Finish receiving an UDP packet. Returns amount of bytes read, or 0 if nothing is read.
 int ioHelperFinishRecvFrom(struct s_io_handle *handle) {
	DWORD len;
	DWORD flags;

	len = 0;
	flags = 0;
	if(handle->ovlr_used) {
		if(WSAGetOverlappedResult(handle->fd, &handle->ovlr, &len, FALSE, &flags) == TRUE) {
			handle->ovlr_used = 0;
			ResetEvent(handle->ovlr.hEvent);
			if(len > 0) {
				handle->content_len = len;
			}
		}
		else {
			if(WSAGetLastError() != WSA_IO_INCOMPLETE) {
				handle->ovlr_used = 0;
				ResetEvent(handle->ovlr.hEvent);
			}				
		}
	}

	if(len > 0) {
		return len;
	}
	else {
		return 0;
	}
}
예제 #3
0
unsigned int SocketReceiver::GetReceiveResult()
{
	if (m_resultPending)
	{
		DWORD flags = 0;
		if (WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags))
		{
			if (m_lastResult == 0)
				m_eofReceived = true;
		}
		else
		{
			switch (WSAGetLastError())
			{
			default:
				m_s.CheckAndHandleError("WSAGetOverlappedResult", FALSE);
			case WSAEDISCON:
				m_lastResult = 0;
				m_eofReceived = true;
			}
		}
		m_resultPending = false;
	}
	return m_lastResult;
}
예제 #4
0
int ff_win_net_complete_overlapped_io(SOCKET socket, WSAOVERLAPPED *overlapped)
{
	struct ff_fiber *current_fiber;
	int int_bytes_transferred = -1;
	BOOL result;
	DWORD flags;
	DWORD bytes_transferred;

	current_fiber = ff_fiber_get_current();
	ff_win_completion_port_register_overlapped_data(net_ctx.completion_port, overlapped, current_fiber);
	ff_core_yield_fiber();
	ff_win_completion_port_deregister_overlapped_data(net_ctx.completion_port, overlapped);

	result = WSAGetOverlappedResult(socket, overlapped, &bytes_transferred, FALSE, &flags);
	if (result != FALSE)
	{
		int_bytes_transferred = (int) bytes_transferred;
	}
	else
	{
		int last_error;

		last_error = WSAGetLastError();
		ff_log_debug(L"the overlapped operation on the socket=%llu, overlapped=%p failed. WSAGetLastError()=%d", (uint64_t) socket, overlapped, last_error);
	}

	return int_bytes_transferred;
}
예제 #5
0
파일: aj_net.c 프로젝트: dengcj0/QCA4010
static AJ_Status AJ_Net_Send(AJ_IOBuffer* buf)
{
    DWORD ret;
    DWORD tx = AJ_IO_BUF_AVAIL(buf);

    AJ_InfoPrintf(("AJ_Net_Send(buf=0x%p)\n", buf));

    assert(buf->direction == AJ_IO_BUF_TX);

    if (tx > 0) {
        NetContext* ctx = (NetContext*) buf->context;
        WSAOVERLAPPED ov;
        DWORD flags = 0;
        WSABUF wsbuf;

        memset(&ov, 0, sizeof(ov));
        ov.hEvent = sendEvent;
        wsbuf.len = tx;
        wsbuf.buf = buf->readPtr;

        ret = WSASend(ctx->tcpSock, &wsbuf, 1, NULL, flags, &ov, NULL);
        if (!WSAGetOverlappedResult(ctx->tcpSock, &ov, &tx, TRUE, &flags)) {
            AJ_ErrPrintf(("AJ_Net_Send(): send() failed. WSAGetLastError()=0x%x, status=AJ_ERR_WRITE\n", WSAGetLastError()));
            return AJ_ERR_WRITE;
        }
        buf->readPtr += tx;
    }
    if (AJ_IO_BUF_AVAIL(buf) == 0) {
        AJ_IO_BUF_RESET(buf);
    }
    AJ_InfoPrintf(("AJ_Net_Send(): status=AJ_OK\n"));
    return AJ_OK;
}
예제 #6
0
/* event manager callback when reads are ready */
static void on_accept(void *arg, int success) {
  server_port *sp = arg;
  SOCKET sock = sp->new_socket;
  grpc_winsocket_callback_info *info = &sp->socket->read_info;
  grpc_endpoint *ep = NULL;

  if (success) {
    DWORD transfered_bytes = 0;
    DWORD flags;
    BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
                                              &transfered_bytes, FALSE,
                                              &flags);
    if (!wsa_success) {
      char *utf8_message = gpr_format_message(WSAGetLastError());
      gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message);
      gpr_free(utf8_message);
      closesocket(sock);
    } else {
      gpr_log(GPR_DEBUG, "on_accept: accepted connection");
      ep = grpc_tcp_create(grpc_winsocket_create(sock));
    }
  } else {
    gpr_log(GPR_DEBUG, "on_accept: shutting down");
    closesocket(sock);
    gpr_mu_lock(&sp->server->mu);
    if (0 == --sp->server->active_ports) {
      gpr_cv_broadcast(&sp->server->cv);
    }
    gpr_mu_unlock(&sp->server->mu);
  }

  if (ep) sp->server->cb(sp->server->cb_arg, ep);
  start_accept(sp);
}
예제 #7
0
파일: aj_net.c 프로젝트: dengcj0/QCA4010
static AJ_Status AJ_ARDP_UDP_Send(void* context, uint8_t* buf, size_t len, size_t* sent)
{
    AJ_Status status = AJ_OK;
    DWORD ret;
    NetContext* ctx = (NetContext*) context;
    WSAOVERLAPPED ov;
    DWORD flags = 0;
    WSABUF wsbuf;

    memset(&ov, 0, sizeof(ov));
    ov.hEvent = sendEvent;
    wsbuf.len = len;
    wsbuf.buf = buf;

    AJ_InfoPrintf(("AJ_ARDP_UDP_Send(buf=0x%p, len=%lu)\n", buf, len));

    ret = WSASend(ctx->udpSock, &wsbuf, 1, NULL, flags, &ov, NULL);
    if (ret == SOCKET_ERROR) {
        AJ_ErrPrintf(("AJ_ARDP_UDP_Send(): WSASend() failed. WSAGetLastError()=0x%x, status=AJ_ERR_WRITE\n", WSAGetLastError()));
        *sent = 0;
        return AJ_ERR_WRITE;
    }

    if (!WSAGetOverlappedResult(ctx->udpSock, &ov, sent, TRUE, &flags)) {
        AJ_ErrPrintf(("AJ_ARDP_UDP_Send(): WSAGetOverlappedResult() failed. WSAGetLastError()=0x%x, status=AJ_ERR_WRITE\n", WSAGetLastError()));
        return AJ_ERR_WRITE;
    }

    return status;
}
예제 #8
0
static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, int from_iocp) {
  async_connect *ac = acp;
  SOCKET sock = ac->socket->socket;
  grpc_endpoint **ep = ac->endpoint;
  grpc_winsocket_callback_info *info = &ac->socket->write_info;
  grpc_closure *on_done = ac->on_done;

  grpc_timer_cancel(exec_ctx, &ac->alarm);

  gpr_mu_lock(&ac->mu);

  if (from_iocp) {
    DWORD transfered_bytes = 0;
    DWORD flags;
    BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
                                              &transfered_bytes, FALSE, &flags);
    GPR_ASSERT(transfered_bytes == 0);
    if (!wsa_success) {
      char *utf8_message = gpr_format_message(WSAGetLastError());
      gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message);
      gpr_free(utf8_message);
    } else {
      *ep = grpc_tcp_create(ac->socket, ac->addr_name);
      ac->socket = NULL;
    }
  }

  async_connect_unlock_and_cleanup(ac);
  /* If the connection was aborted, the callback was already called when
     the deadline was met. */
  on_done->cb(exec_ctx, on_done->cb_arg, *ep != NULL);
}
void NetworkConnection::dataReceived()
{
	if (!closed)	// Ignore call if connection is closed
	{	
		BOOL operationSucceeded = 	// Call receive 
			WSAGetOverlappedResult(connection, &receiveOverlapped, 
										&bytesReceived, FALSE, &flags);
		// If anything went wrong, didnt receive anything or 
		// the send error flag was set
		if (!operationSucceeded || bytesReceived < 1 || sendError)
		{		// If not blocking error
			if (WSAGetLastError() != WSA_IO_INCOMPLETE)	
				close();	// Close connection
			else			// If not, continue waiting
				continueReceive();	
		}
		else
		{		// If receiver object associated, let them know data is 
			if (dataReceiver != nullptr)	// received
				dataReceiver->receivedData(receiveBuffer, 
											(int)bytesReceived);

			continueReceive();	// wait for more data
		}
	}
}
예제 #10
0
int WSARead(SOCKET sd, char * message, int timeout, int size){
    WSAOVERLAPPED ov;
    DWORD recvBytes;
    DWORD recvErr;
    DWORD flags = 0;
    WSABUF dbuf;
    dbuf.buf = message;
    dbuf.len = size;
    ov.hEvent = WSACreateEvent();
    if ((recvErr = WSARecv(sd, &dbuf, 1, &recvBytes,&flags, &ov, NULL)) == SOCKET_ERROR)
    {
        recvErr = WSAGetLastError();
        if (recvErr != WSA_IO_PENDING) {

            return 0;
        }
    }

    recvErr = WSAWaitForMultipleEvents(1, &ov.hEvent, FALSE, timeout, FALSE);
    switch (recvErr)
    {
    case WAIT_TIMEOUT:
        return 0;
        break;
    case WAIT_FAILED:
        exit(1);
        break;
    default:
        break;
    }
    int x = strlen(dbuf.buf);
    int rc = WSAGetOverlappedResult(sd, &ov, &recvBytes, FALSE, &flags);
    return recvBytes;

}
예제 #11
0
파일: io.c 프로젝트: beebee/peervpn
// Sends an IPv4 UDP packet. Returns length of sent message.
static int ioSendUDPv4Packet(struct s_io_state *iostate, const unsigned char *buf, const int len, const struct s_io_v4addr *destination) {
	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_family = AF_INET;
	memcpy(&addr.sin_addr.s_addr, destination->addr, 4);
	memcpy(&addr.sin_port, destination->port, 2);
#ifdef IO_WINDOWS
	DWORD ret = 0;
	DWORD flags = 0;
	WSABUF wsabuf;
	wsabuf.buf = (char *)buf;
	wsabuf.len = len;
	WSASendTo(iostate->fd[IO_FDID_UDPV4SOCKET].fd, &wsabuf, 1, NULL, flags, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), &iostate->overlapped_write[IO_FDID_UDPV4SOCKET], NULL);
	WSAGetOverlappedResult(iostate->fd[IO_FDID_UDPV4SOCKET].fd, &iostate->overlapped_write[IO_FDID_UDPV4SOCKET], &ret, TRUE, &flags);
#else
	int ret;
	ret = sendto(iostate->fd[IO_FDID_UDPV4SOCKET].fd, buf, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
#endif
	if(ret > 0) {
		return ret;
	}
	else {
		return 0;
	}
}
예제 #12
0
파일: iocp_windows.c 프로젝트: kokoar/grpc
static void do_iocp_work() {
  BOOL success;
  DWORD bytes = 0;
  DWORD flags = 0;
  ULONG_PTR completion_key;
  LPOVERLAPPED overlapped;
  gpr_timespec wait_time = gpr_inf_future;
  grpc_winsocket *socket;
  grpc_winsocket_callback_info *info;
  void(*f)(void *, int) = NULL;
  void *opaque = NULL;
  success = GetQueuedCompletionStatus(g_iocp, &bytes,
                                      &completion_key, &overlapped,
                                      gpr_time_to_millis(wait_time));
  if (!success && !overlapped) {
    /* The deadline got attained. */
    return;
  }
  GPR_ASSERT(completion_key && overlapped);
  if (overlapped == &g_iocp_custom_overlap) {
    if (completion_key == (ULONG_PTR) &g_iocp_kick_token) {
      /* We were awoken from a kick. */
      return;
    }
    gpr_log(GPR_ERROR, "Unknown custom completion key.");
    abort();
  }

  socket = (grpc_winsocket*) completion_key;
  if (overlapped == &socket->write_info.overlapped) {
    info = &socket->write_info;
  } else if (overlapped == &socket->read_info.overlapped) {
    info = &socket->read_info;
  } else {
    gpr_log(GPR_ERROR, "Unknown IOCP operation");
    abort();
  }
  success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes,
                                   FALSE, &flags);
  if (socket->orphan) {
    grpc_winsocket_destroy(socket);
    gpr_atm_full_fetch_add(&g_orphans, -1);
    return;
  }
  info->bytes_transfered = bytes;
  info->wsa_error = success ? 0 : WSAGetLastError();
  GPR_ASSERT(overlapped == &info->overlapped);
  gpr_mu_lock(&socket->state_mu);
  GPR_ASSERT(!info->has_pending_iocp);
  if (info->cb) {
    f = info->cb;
    opaque = info->opaque;
    info->cb = NULL;
  } else {
    info->has_pending_iocp = 1;
  }
  gpr_mu_unlock(&socket->state_mu);
  if (f) f(opaque, 1);
}
예제 #13
0
//sends a message, or part of one
int CPassiveSock::Send(const void * const lpBuf, const int Len)
{
    WSAOVERLAPPED os;
    WSABUF buffers[2];
    WSAEVENT hEvents[2] = {NULL,NULL};
    DWORD
    dwWait,
    bytes_sent=0,
    msg_flags = 0;

    // Setup up the events to wait on
    hEvents[1] = write_event;
    hEvents[0] = m_hStopEvent;
    // Setup the buffers array
    buffers[0].buf = (char *)lpBuf;
    buffers[0].len = Len;
    msg_flags = 0;
    dwWait = 0;
    int rc;

    LastError = 0;

    // Create the overlapped I/O event and structures
    memset(&os, 0, sizeof(OVERLAPPED));
    os.hEvent = write_event;
    WSAResetEvent(read_event);
    rc = WSASend(ActualSocket, buffers, 1, &bytes_sent, 0, &os, NULL);
    LastError=WSAGetLastError();
    if ((rc == SOCKET_ERROR) && (LastError == WSA_IO_PENDING))  // Write in progress
    {
        CTimeSpan TimeLeft = SendEndTime - CTime::GetCurrentTime();
        dwWait = WaitForMultipleObjects(2, hEvents, false, (DWORD)TimeLeft.GetTotalSeconds()*1000);
        if (dwWait == WAIT_OBJECT_0+1) // I/O completed
        {
            if (WSAGetOverlappedResult(ActualSocket, &os, &bytes_sent, true, &msg_flags))
                return bytes_sent;
        }
    }
    else if (!rc) // if rc is zero, the read was completed immediately
    {
        if (WSAGetOverlappedResult(ActualSocket, &os, &bytes_sent, true, &msg_flags))
            return bytes_sent;
    }
    return SOCKET_ERROR;
}
예제 #14
0
ConnectionPtr SocketConnection::acceptSync()
{
    LB_TS_THREAD( _recvThread );
    if( !isListening( ))
        return 0;

    LBASSERT( _overlappedAcceptData );
    LBASSERT( _overlappedSocket != INVALID_SOCKET );
    if( _overlappedSocket == INVALID_SOCKET )
        return 0;

    // complete accept
    DWORD got   = 0;
    DWORD flags = 0;

    if( !WSAGetOverlappedResult( _readFD, &_overlappedRead, &got, TRUE,
                                 &flags ))
    {
        LBWARN << "Accept completion failed: " << lunchbox::sysError
               << ", closing socket" << std::endl;
        close();
        return 0;
    }

    sockaddr_in* local     = 0;
    sockaddr_in* remote    = 0;
    int          localLen  = 0;
    int          remoteLen = 0;
    GetAcceptExSockaddrs( _overlappedAcceptData, 0, sizeof( sockaddr_in ) + 16,
                          sizeof( sockaddr_in ) + 16, (sockaddr**)&local,
                          &localLen, (sockaddr**)&remote, &remoteLen );
    _tuneSocket( _overlappedSocket );

    ConstConnectionDescriptionPtr description = getDescription();
    SocketConnection* newConnection = new SocketConnection;
    ConnectionPtr connection( newConnection ); // to keep ref-counting correct

    newConnection->_readFD  = _overlappedSocket;
    newConnection->_writeFD = _overlappedSocket;

#ifndef _WIN32
    //fcntl( _overlappedSocket, F_SETFL, O_NONBLOCK );
#endif

    newConnection->_initAIORead();
    _overlappedSocket       = INVALID_SOCKET;

    newConnection->_setState( STATE_CONNECTED );
    ConnectionDescriptionPtr newDescription = newConnection->_getDescription();
    newDescription->bandwidth = description->bandwidth;
    newDescription->port = ntohs( remote->sin_port );
    newDescription->setHostname( getHostName( *remote ));

    LBDEBUG << "accepted connection from " << newDescription->getHostname()
           << ":" << newDescription->port << std::endl;
    return connection;
}
예제 #15
0
/* GetQueuedCompletionStatus doesn't reliably yield WSA error codes, so
 * we use WSAGetOverlappedResult to translate. */
static void
bev_async_set_wsa_error(struct bufferevent *bev, struct event_overlapped *eo)
{
	DWORD bytes, flags;
	evutil_socket_t fd;

	fd = _evbuffer_overlapped_get_fd(bev->input);
	WSAGetOverlappedResult(fd, &eo->overlapped, &bytes, FALSE, &flags);
}
예제 #16
0
unsigned int SocketSender::GetSendResult()
{
	if (m_resultPending)
	{
		DWORD flags = 0;
		BOOL result = WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags);
		m_s.CheckAndHandleError("WSAGetOverlappedResult", result);
		m_resultPending = false;
	}
	return m_lastResult;
}
예제 #17
0
파일: aj_net.c 프로젝트: dengcj0/QCA4010
static AJ_Status AJ_ARDP_UDP_Recv(void* context, uint8_t** data, uint32_t* recved, uint32_t timeout)
{
    NetContext* ctx = (NetContext*) context;
    DWORD ret = SOCKET_ERROR;
    WSAEVENT events[2];
    DWORD flags = 0;
    static uint8_t buffer[UDP_SEGBMAX];

    *data = NULL;

    if (wsaOverlapped.hEvent == INVALID_HANDLE_VALUE) {
        wsbuf.len = sizeof(buffer);
        wsbuf.buf = buffer;
        memset(&wsaOverlapped, 0, sizeof(WSAOVERLAPPED));
        wsaOverlapped.hEvent = recvEvent;
        ret = WSARecvFrom(ctx->udpSock, &wsbuf, 1, NULL, &flags, NULL, NULL, &wsaOverlapped, NULL);
        if ((ret == SOCKET_ERROR) && (WSAGetLastError() != WSA_IO_PENDING)) {
            AJ_ErrPrintf(("WSARecvFrom(): failed WSAGetLastError()=%d\n", WSAGetLastError()));
            return AJ_ERR_READ;
        }
    }

    events[0] = wsaOverlapped.hEvent;
    events[1] = interruptEvent;

    ret = WSAWaitForMultipleEvents(2, events, FALSE, timeout, TRUE);
    switch (ret) {
    case WSA_WAIT_EVENT_0:
        flags = 0;
        if (WSAGetOverlappedResult(ctx->udpSock, &wsaOverlapped, recved, TRUE, &flags)) {
            WSAResetEvent(wsaOverlapped.hEvent);
            wsaOverlapped.hEvent = INVALID_HANDLE_VALUE;
            *data = buffer;
            return AJ_OK;
        } else {
            AJ_ErrPrintf(("AJ_ARDP_UDP_Recv(): WSAGetOverlappedResult error; WSAGetLastError()=%d\n", WSAGetLastError()));
            return AJ_ERR_READ;
        }
        break;

    case WSA_WAIT_EVENT_0 + 1:
        WSAResetEvent(interruptEvent);
        return AJ_ERR_INTERRUPTED;

    case WSA_WAIT_TIMEOUT:
        return AJ_ERR_TIMEOUT;
        break;

    default:
        AJ_ErrPrintf(("AJ_ARDP_UDP_Recv(): WSAWaitForMultipleEvents error; WSAGetLastError()=%d\n", WSAGetLastError()));
        return AJ_ERR_READ;
    }
}
예제 #18
0
int IOCPMonitor::GetError(SOCKET sock, WSAOVERLAPPED* pWSAOVERLAPPED)  
{  
#ifdef WIN32
	DWORD dwTrans;  
	DWORD dwFlags;  
	if(FALSE == WSAGetOverlappedResult(sock, pWSAOVERLAPPED, &dwTrans, FALSE, &dwFlags))  
		return WSAGetLastError();  
	else  
		return ERROR_SUCCESS;  
#endif
	return 0;
}  
예제 #19
0
파일: iocp_windows.c 프로젝트: nimrodp/grpc
void grpc_iocp_work(grpc_exec_ctx *exec_ctx, gpr_timespec deadline) {
  BOOL success;
  DWORD bytes = 0;
  DWORD flags = 0;
  ULONG_PTR completion_key;
  LPOVERLAPPED overlapped;
  grpc_winsocket *socket;
  grpc_winsocket_callback_info *info;
  grpc_closure *closure = NULL;
  success = GetQueuedCompletionStatus(
      g_iocp, &bytes, &completion_key, &overlapped,
      deadline_to_millis_timeout(deadline, gpr_now(deadline.clock_type)));
  if (success == 0 && overlapped == NULL) {
    return;
  }
  GPR_ASSERT(completion_key && overlapped);
  if (overlapped == &g_iocp_custom_overlap) {
    gpr_atm_full_fetch_add(&g_custom_events, -1);
    if (completion_key == (ULONG_PTR)&g_iocp_kick_token) {
      /* We were awoken from a kick. */
      return;
    }
    gpr_log(GPR_ERROR, "Unknown custom completion key.");
    abort();
  }

  socket = (grpc_winsocket *)completion_key;
  if (overlapped == &socket->write_info.overlapped) {
    info = &socket->write_info;
  } else if (overlapped == &socket->read_info.overlapped) {
    info = &socket->read_info;
  } else {
    gpr_log(GPR_ERROR, "Unknown IOCP operation");
    abort();
  }
  success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes,
                                   FALSE, &flags);
  info->bytes_transfered = bytes;
  info->wsa_error = success ? 0 : WSAGetLastError();
  GPR_ASSERT(overlapped == &info->overlapped);
  GPR_ASSERT(!info->has_pending_iocp);
  gpr_mu_lock(&socket->state_mu);
  if (info->closure) {
    closure = info->closure;
    info->closure = NULL;
  } else {
    info->has_pending_iocp = 1;
  }
  gpr_mu_unlock(&socket->state_mu);
  grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL);
}
예제 #20
0
OverlappedTransferBuffer *Socket::BeginSend(int maxBytesToSend)
{
	if (!writeOpen)
		return 0;

	// See if the oldest one of the previously submitted transfers has now finished,
	// and reuse that buffer without allocating a new one, if so.
#ifdef WIN32
	if (queuedSendBuffers.Size() > 0)
	{
		OverlappedTransferBuffer *sentData = *queuedSendBuffers.Front();
		DWORD flags = 0;
		BOOL ret = WSAGetOverlappedResult(connectSocket, &sentData->overlapped, (LPDWORD)&sentData->bytesContains, 
			(queuedSendBuffers.CapacityLeft() == 0) ? TRUE : FALSE, &flags);
		int error = (ret == TRUE) ? 0 : Network::GetLastError();
		if (ret == TRUE)
		{
			queuedSendBuffers.PopFront();

            // If the buffer we pulled off was too small, free it and allocate a new one which is of the desired size.
            if (sentData->bytesAllocated < maxBytesToSend)
            {
                DeleteOverlappedTransferBuffer(sentData);
	            return AllocateOverlappedTransferBuffer(maxBytesToSend); ///\todo In debug mode - track this pointer.
            }
            else
            {
                // The existing transfer buffer is large enough. Prepare it for reuse and pass back to caller.
			    sentData->buffer.len = sentData->bytesAllocated; // This is the number of bytes that the client is allowed to fill.
			    sentData->bytesContains = 0; // No bytes currently in use.

			    return sentData;
            }
		}
		if (ret == FALSE && error != WSA_IO_INCOMPLETE)
		{
			LOG(LogError, "Socket::BeginSend: WSAGetOverlappedResult failed with an error %s, code %d != WSA_IO_INCOMPLETE!", 
				Network::GetErrorString(error).c_str(), error);
			writeOpen = false;
			return 0;
		}
	}

	if (queuedSendBuffers.CapacityLeft() == 0)
		return 0;
#endif

	// No previous send buffer has finished from use (or not using overlapped transfers) - allocate a new buffer.
	return AllocateOverlappedTransferBuffer(maxBytesToSend);
}
예제 #21
0
int send_nblk( SOCKET s, char *buf, int len, int flags, unsigned int timeout, CTCPIPSystemDrvr* pTCPIPSystem)
{
	unsigned long sflags = 0;
	int nLeft = len;
	int idx = 0;
	int retcode;
	long lastResult; 

	DWORD written = 0;
	WSABUF wsabuf;
	WSAOVERLAPPED overlapped;

	SEND_INFO si;
	si.hEvent = pTCPIPSystem->m_hEvents[1];
	si.s = s;
	si.timeout = timeout;

	overlapped.hEvent = pTCPIPSystem->m_hEvents[1];

	while (nLeft > 0)
	{
		wsabuf.buf = &buf[idx];
		wsabuf.len = nLeft;
		if (WSASend(s, &wsabuf, 1, &written, 0, &overlapped, NULL) == 0)
		{
			lastResult = written;
		}
		else
		{
			if (WSAGetLastError() != WSA_IO_PENDING)
			{
				(fpTCPIPSET_ERROR)((long)pTCPIPSystem, PC, TCPIP, pTCPIPSystem->odbcAPI, E_DRIVER, pTCPIPSystem->m_object_ref, O_DO_WRITE_READ, F_SEND, WSAGetLastError(), (int)0);
				return false;
			}
			retcode = wait_for_event(&si, FD_WRITE, pTCPIPSystem);
			if (retcode == 0)
				return false;
			if (FALSE==WSAGetOverlappedResult(s, &overlapped, &written, false, &sflags))
			{
				(fpTCPIPSET_ERROR)((long)pTCPIPSystem, PC, TCPIP, pTCPIPSystem->odbcAPI, E_DRIVER, pTCPIPSystem->m_object_ref, O_DO_WRITE_READ, F_SEND_GETOVERLAPPEDRESULTS, WSAGetLastError(), (int)0);
				return false;
			}
			lastResult = written;
		}

		nLeft -= lastResult;
		idx += lastResult;
	}
	return idx;
}
예제 #22
0
std::size_t TcpConnection::write(const uint8_t* data, size_t size) {
  assert(dispatcher != nullptr);
  assert(writeContext == nullptr);
  if (stopped) {
    throw InterruptedException();
  }

  if (size == 0) {
    if (shutdown(connection, SD_SEND) != 0) {
      throw std::runtime_error("TcpConnection::write, shutdown failed, result=" + std::to_string(WSAGetLastError()));
    }

    return 0;
  }

  WSABUF buf{static_cast<ULONG>(size), reinterpret_cast<char*>(const_cast<uint8_t*>(data))};
  TcpConnectionContext context;
  context.hEvent = NULL;
  if (WSASend(connection, &buf, 1, NULL, 0, &context, NULL) != 0) {
    int lastError = WSAGetLastError();
    if (lastError != WSA_IO_PENDING) {
      throw std::runtime_error("TcpConnection::write, WSASend failed, result=" + std::to_string(lastError));
    }
  }

  context.context = GetCurrentFiber();
  context.interrupted = false;
  writeContext = &context;
  dispatcher->dispatch();
  assert(context.context == GetCurrentFiber());
  assert(dispatcher != nullptr);
  assert(writeContext == &context);
  writeContext = nullptr;
  DWORD transferred;
  DWORD flags;
  if (WSAGetOverlappedResult(connection, &context, &transferred, FALSE, &flags) != TRUE) {
    int lastError = WSAGetLastError();
    if (lastError != ERROR_OPERATION_ABORTED) {
      throw std::runtime_error("TcpConnection::write, WSASend failed, result=" + std::to_string(lastError));
    }

    assert(context.interrupted);
    throw InterruptedException();
  }

  assert(transferred == size);
  assert(flags == 0);
  return transferred;
}
예제 #23
0
파일: io.c 프로젝트: hideman-ltd/peervpn
// Sends an UDP packet. Returns length of sent message.
 int ioHelperSendTo(struct s_io_handle *handle, const unsigned char *send_buf, const int send_buf_size, const struct sockaddr *destination_sockaddr, const socklen_t destination_sockaddr_len) {
	int len;

#if defined(IO_LINUX) || defined(IO_BSD)

	len = sendto(handle->fd, send_buf, send_buf_size, 0, destination_sockaddr, destination_sockaddr_len);

#elif defined(IO_WINDOWS)

	int ovlw_used;
	WSABUF wsabuf;
	DWORD flags;
	DWORD dwlen;

	len = 0;
	wsabuf.buf = (char *)send_buf;
	wsabuf.len = send_buf_size;
	flags = 0;
	ovlw_used = 0;
	if(WSASendTo(handle->fd, &wsabuf, 1, NULL, flags, destination_sockaddr, destination_sockaddr_len, &handle->ovlw, NULL) == 0) {
		ovlw_used = 1;
	}
	else {
		if(WSAGetLastError() == WSA_IO_PENDING) {
			ovlw_used = 1;
		}
	}
	if(ovlw_used) {
		if(WSAGetOverlappedResult(handle->fd, &handle->ovlw, &dwlen, TRUE, &flags) == TRUE) {	
			len = dwlen;
		}
		ResetEvent(handle->ovlw.hEvent);
	}

#else

	#error not implemented
	len = 0;

#endif

	if(len > 0) {
		return len;
	}
	else {
		return 0;
	}
}
예제 #24
0
ConnectionPtr PGMConnection::acceptSync()
{
    EQ_TS_THREAD( _recvThread );
    if( _state != STATE_LISTENING )
        return 0;

    EQASSERT( _overlappedAcceptData );
    EQASSERT( _overlappedSocket != INVALID_SOCKET );
    if( _overlappedSocket == INVALID_SOCKET )
        return 0;

    // complete accept
    DWORD got   = 0;
    DWORD flags = 0;
    if( !WSAGetOverlappedResult( _readFD, &_overlapped, &got, TRUE, &flags ))
    {
        EQWARN << "Accept completion failed: " << base::sysError 
               << ", closing connection" << std::endl;
        close();
        return 0;
    }

    sockaddr_in* local     = 0;
    sockaddr_in* remote    = 0;
    int          localLen  = 0;
    int          remoteLen = 0;
    GetAcceptExSockaddrs( _overlappedAcceptData, 0, sizeof( sockaddr_in ) + 16,
                          sizeof( sockaddr_in ) + 16, (sockaddr**)&local, 
                          &localLen, (sockaddr**)&remote, &remoteLen );

    PGMConnection* newConnection = new PGMConnection;
    ConnectionPtr connection( newConnection ); // to keep ref-counting correct

    newConnection->_readFD  = _overlappedSocket;
    _overlappedSocket       = INVALID_SOCKET;

    newConnection->_setupReadSocket();
    newConnection->_writeFD = _writeFD;
    newConnection->_initAIORead();
    newConnection->_state       = STATE_CONNECTED;
    newConnection->_description = _description;

    EQINFO << "accepted connection " << (void*)newConnection << " from " 
           << inet_ntoa( remote->sin_addr ) << ":" << ntohs( remote->sin_port )
           << std::endl;
    return connection;
}
void main(int argc,char**argv){
	WSADATA wsaData;
	SOCKET sock;
	SOCKADDR_IN sendAddr;

	WSABUF dataBuf;
	char msg[]="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
	int sendBytes=0;
	WSAEVENT eventObject;
	WSAOVERLAPPED overlapped;

	if(argc!=3){
		printf("Usage : %s <IP> <PORT> \n",argv[0]);
		exit(1);
	}

	if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) ErrorHandling("WSAStartup error");

	sock=WSASocket(PF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
	memset(&sendAddr,0,sizeof(sendAddr));
	sendAddr.sin_family=AF_INET;
	sendAddr.sin_port=htons(atoi(argv[2]));
	sendAddr.sin_addr.s_addr=inet_addr(argv[1]);

	if(connect(sock,(SOCKADDR*)&sendAddr,sizeof(sendAddr))==SOCKET_ERROR) ErrorHandling("connect error");

	eventObject=WSACreateEvent();
	memset(&overlapped,0,sizeof(overlapped));
	dataBuf.len=strlen(msg)+1;
	dataBuf.buf=msg;

	if(WSASend(sock,&dataBuf,1,&sendBytes,0,&overlapped,NULL)==SOCKET_ERROR){
		if(WSAGetLastError()==WSA_IO_PENDING){ //전송할 데이터가 남아 있는 상태
			puts("Background data send");
			WSAWaitForMultipleEvents(1,&eventObject,TRUE,WSA_INFINITE,FALSE);
			WSAGetOverlappedResult(sock,&overlapped,&sendBytes,FALSE,NULL);
		}
		else ErrorHandling("WSASend error");
	}

	printf("Send data size : %d \n",sendBytes);
	WSACloseEvent(eventObject);
	closesocket(sock);
	WSACleanup();
}
예제 #26
0
static void
accepted_socket_cb(struct event_overlapped *o, ev_uintptr_t key, ev_ssize_t n, int ok)
{
	struct accepting_socket *as =
	    EVUTIL_UPCAST(o, struct accepting_socket, overlapped);

	LOCK(&as->lev->base);
	EnterCriticalSection(&as->lock);
	if (ok) {
		/* XXXX Don't do this if some EV_MT flag is set. */
		event_deferred_cb_schedule(
			event_base_get_deferred_cb_queue(as->lev->event_base),
			&as->deferred);
		LeaveCriticalSection(&as->lock);
	} else if (as->free_on_cb) {
		struct evconnlistener *lev = &as->lev->base;
		free_and_unlock_accepting_socket(as);
		listener_decref_and_unlock(lev);
		return;
	} else if (as->s == INVALID_SOCKET) {
		/* This is okay; we were disabled by iocp_listener_disable. */
		LeaveCriticalSection(&as->lock);
	} else {
		/* Some error on accept that we couldn't actually handle. */
		BOOL ok;
		DWORD transfer = 0, flags=0;
		event_sock_warn(as->s, "Unexpected error on AcceptEx");
		ok = WSAGetOverlappedResult(as->s, &o->overlapped,
		    &transfer, FALSE, &flags);
		if (ok) {
			/* well, that was confusing! */
			as->error = 1;
		} else {
			as->error = WSAGetLastError();
		}
		event_deferred_cb_schedule(
			event_base_get_deferred_cb_queue(as->lev->event_base),
			&as->deferred);
		LeaveCriticalSection(&as->lock);
	}
	UNLOCK(&as->lev->base);
}
예제 #27
0
size_t TcpConnection::read(uint8_t* data, size_t size) {
  assert(dispatcher != nullptr);
  assert(readContext == nullptr);
  if (stopped) {
    throw InterruptedException();
  }

  WSABUF buf{static_cast<ULONG>(size), reinterpret_cast<char*>(data)};
  DWORD flags = 0;
  TcpConnectionContext context;
  context.hEvent = NULL;
  if (WSARecv(connection, &buf, 1, NULL, &flags, &context, NULL) != 0) {
    int lastError = WSAGetLastError();
    if (lastError != WSA_IO_PENDING) {
      throw std::runtime_error("TcpConnection::read, WSARecv failed, result=" + std::to_string(lastError));
    }
  }

  assert(flags == 0);
  context.context = GetCurrentFiber();
  context.interrupted = false;
  readContext = &context;
  dispatcher->dispatch();
  assert(context.context == GetCurrentFiber());
  assert(dispatcher != nullptr);
  assert(readContext == &context);
  readContext = nullptr;
  DWORD transferred;
  if (WSAGetOverlappedResult(connection, &context, &transferred, FALSE, &flags) != TRUE) {
    int lastError = WSAGetLastError();
    if (lastError != ERROR_OPERATION_ABORTED) {
      throw std::runtime_error("TcpConnection::read, WSARecv failed, result=" + std::to_string(lastError));
    }

    assert(context.interrupted);
    throw InterruptedException();
  }

  assert(transferred <= size);
  assert(flags == 0);
  return transferred;
}
예제 #28
0
파일: iocp_windows.c 프로젝트: Indifer/grpc
grpc_iocp_work_status grpc_iocp_work(grpc_exec_ctx *exec_ctx,
                                     gpr_timespec deadline) {
  BOOL success;
  DWORD bytes = 0;
  DWORD flags = 0;
  ULONG_PTR completion_key;
  LPOVERLAPPED overlapped;
  grpc_winsocket *socket;
  grpc_winsocket_callback_info *info;
  success = GetQueuedCompletionStatus(
      g_iocp, &bytes, &completion_key, &overlapped,
      deadline_to_millis_timeout(deadline, gpr_now(deadline.clock_type)));
  if (success == 0 && overlapped == NULL) {
    return GRPC_IOCP_WORK_TIMEOUT;
  }
  GPR_ASSERT(completion_key && overlapped);
  if (overlapped == &g_iocp_custom_overlap) {
    gpr_atm_full_fetch_add(&g_custom_events, -1);
    if (completion_key == (ULONG_PTR)&g_iocp_kick_token) {
      /* We were awoken from a kick. */
      return GRPC_IOCP_WORK_KICK;
    }
    gpr_log(GPR_ERROR, "Unknown custom completion key.");
    abort();
  }

  socket = (grpc_winsocket *)completion_key;
  if (overlapped == &socket->write_info.overlapped) {
    info = &socket->write_info;
  } else if (overlapped == &socket->read_info.overlapped) {
    info = &socket->read_info;
  } else {
    abort();
  }
  success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes,
                                   FALSE, &flags);
  info->bytes_transfered = bytes;
  info->wsa_error = success ? 0 : WSAGetLastError();
  GPR_ASSERT(overlapped == &info->overlapped);
  grpc_socket_become_ready(exec_ctx, socket, info);
  return GRPC_IOCP_WORK_WORK;
}
예제 #29
0
bool Socket::IsOverlappedSendReady()
{
	if (!writeOpen)
		return false;

#ifdef WIN32
	if (queuedSendBuffers.CapacityLeft() > 0)
		return true;

	OverlappedTransferBuffer *sentData = *queuedSendBuffers.Front();
	DWORD flags = 0;
	BOOL ret = WSAGetOverlappedResult(connectSocket, &sentData->overlapped, (LPDWORD)&sentData->bytesContains, 
		FALSE, &flags);
	return ret == TRUE;
#else
	EventArray ea;
	ea.AddEvent(Event(connectSocket, EventWaitWrite));
	return ea.Wait(0) == 0;
#endif
}
예제 #30
0
static void on_connect(void *acp, int success) {
  async_connect *ac = acp;
  SOCKET sock = ac->socket->socket;
  grpc_endpoint *ep = NULL;
  grpc_winsocket_callback_info *info = &ac->socket->write_info;
  void(*cb)(void *arg, grpc_endpoint *tcp) = ac->cb;
  void *cb_arg = ac->cb_arg;

  grpc_alarm_cancel(&ac->alarm);

  if (success) {
    DWORD transfered_bytes = 0;
    DWORD flags;
    BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
                                              &transfered_bytes, FALSE,
                                              &flags);
    GPR_ASSERT(transfered_bytes == 0);
    if (!wsa_success) {
      char *utf8_message = gpr_format_message(WSAGetLastError());
      gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message);
      gpr_free(utf8_message);
      goto finish;
    } else {
      ep = grpc_tcp_create(ac->socket);
      goto finish;
    }
  } else {
    gpr_log(GPR_ERROR, "on_connect is shutting down");
    goto finish;
  }

  abort();

finish:
  gpr_mu_lock(&ac->mu);
  if (!ep) {
    grpc_winsocket_orphan(ac->socket);
  }
  async_connect_cleanup(ac);
  cb(cb_arg, ep);
}