⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntp_iocompletionport.c

📁 基于ntp协议的网络时间服务程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		msyslog(LOG_ERR, "Can't allocate memory for clock socket: %m");		FreeHeap(lpo, "io_completion_port_add_clock_io");		return 1;	}	QueueIORead( rio, buff, lpo );	return 0;}/* Queue a receiver on a socket. Returns 0 if no buffer can be queued */static unsigned long QueueSocketRecv(SOCKET s, recvbuf_t *buff, IoCompletionInfo *lpo) {		int AddrLen;	lpo->request_type = SOCK_RECV;	lpo->recv_buf = buff;	if (buff != NULL) {		DWORD BytesReceived = 0;		DWORD Flags = 0;		buff->fd = s;		AddrLen = sizeof(struct sockaddr_in);		buff->src_addr_len = sizeof(struct sockaddr);		if (SOCKET_ERROR == WSARecvFrom(buff->fd, &buff->wsabuff, 1, 						&BytesReceived, &Flags, 						(struct sockaddr *) &buff->recv_srcadr, (LPINT) &buff->src_addr_len, 						(LPOVERLAPPED) lpo, NULL)) {			DWORD Result = WSAGetLastError();			switch (Result) {				case NO_ERROR :				case WSA_IO_INCOMPLETE :				case WSA_WAIT_IO_COMPLETION :				case WSA_IO_PENDING :					break ;				case WSAENOTSOCK :					netsyslog(LOG_ERR, "Can't read from socket, because it isn't a socket: %m");					/* return the buffer */					freerecvbuf(buff);					return 0;					break;				case WSAEFAULT :					netsyslog(LOG_ERR, "The buffers parameter is incorrect: %m");					/* return the buffer */					freerecvbuf(buff);					return 0;				break;				default :				  /* nop */ ;			}		}	}	else 		return 0;	return 1;}/* Returns 0 if any Error */static int OnSocketRecv(DWORD i, IoCompletionInfo *lpo, DWORD Bytes, int errstatus){	struct recvbuf *buff = NULL;	recvbuf_t *newbuff;	isc_boolean_t ignore_this;	l_fp arrival_time;	struct interface * inter = (struct interface *) i;		get_systime(&arrival_time);		/*  Convert the overlapped pointer back to a recvbuf pointer.	*/		/*	 * Check returned structures	 */	if (lpo == NULL)		return (1); /* Nothing to do */	buff = lpo->recv_buf;	/*	 * Make sure we have a buffer	 */	if (buff == NULL) {		return (1);	}	/*	 * If the socket is closed we get an Operation Aborted error	 * Just clean up	 */	if (errstatus == WSA_OPERATION_ABORTED)	{		freerecvbuf(buff);		FreeHeap(lpo, "OnSocketRecv: Socket Closed");		return (1);	}	/*	 * Get a new recv buffer for the next packet	 */	newbuff = get_free_recv_buffer_alloc();	if (newbuff == NULL) {		/*		 * recv buffers not available so we drop the packet		 * and reuse the buffer.		 */		newbuff = buff;	}	else 	{		ignore_this = inter->ignore_packets;		/*		 * If we keep it add some info to the structure		 */		if (Bytes > 0 && ignore_this == ISC_FALSE) {			memcpy(&buff->recv_time, &arrival_time, sizeof(arrival_time));				buff->recv_length = (int) Bytes;			buff->receiver = receive; 			buff->dstadr = inter;#ifdef DEBUG			if (debug > 1)  				printf("Received %d bytes of fd %d in buffer %x from %s\n", Bytes, buff->fd, buff, stoa(&buff->recv_srcadr));#endif			add_full_recv_buffer(buff);			/*			 * Now signal we have something to process			 */			if( !SetEvent( WaitableIoEventHandle ) ) {#ifdef DEBUG				if (debug > 1) {					printf( "Error %d setting IoEventHandle\n", GetLastError() );				}#endif			}		}		else {			freerecvbuf(buff);		}	}	if (newbuff != NULL)		QueueSocketRecv(inter->fd, newbuff, lpo);	return 1;}/*  Add a socket handle to the I/O completion port, and send an I/O *  read request to the kernel. * *  Note: As per the winsock documentation, we use WSARecvFrom. Using *        ReadFile() is less efficient. */extern intio_completion_port_add_socket(SOCKET fd, struct interface *inter){	IoCompletionInfo *lpo;	recvbuf_t *buff;	if (fd != INVALID_SOCKET) {		if (NULL == CreateIoCompletionPort((HANDLE) fd, hIoCompletionPort,						   (DWORD) inter, 0)) {			msyslog(LOG_ERR, "Can't add socket to i/o completion port: %m");			return 1;		}	}	lpo = (IoCompletionInfo *) GetHeapAlloc("io_completion_port_add_socket");	if (lpo == NULL)	{		msyslog(LOG_ERR, "Can't allocate heap for completion port: %m");		return 1;	}	buff = get_free_recv_buffer_alloc();	if (buff == NULL)	{		msyslog(LOG_ERR, "Can't allocate memory for network socket: %m");		FreeHeap(lpo, "io_completion_port_add_socket");		return 1;	}	QueueSocketRecv(fd, buff, lpo);	return 0;}static int OnWriteComplete(DWORD Key, IoCompletionInfo *lpo, DWORD Bytes, int errstatus){	transmitbuf_t *buff;	(void) Bytes;	(void) Key;	buff = lpo->trans_buf;	free_trans_buf(buff);	if (errstatus == WSA_OPERATION_ABORTED)		FreeHeap(lpo, "OnWriteComplete: Socket Closed");	else		FreeHeap(lpo, "OnWriteComplete");	return 1;}DWORD	io_completion_port_sendto(	struct interface *inter,		struct pkt *pkt,		int len, 	struct sockaddr_storage* dest){	transmitbuf_t *buff = NULL;	DWORD Result = ERROR_SUCCESS;	int errval;	int AddrLen;	IoCompletionInfo *lpo;	DWORD BytesSent = 0;	DWORD Flags = 0;	lpo = (IoCompletionInfo *) GetHeapAlloc("io_completion_port_sendto");	if (lpo == NULL)		return ERROR_OUTOFMEMORY;	if (len <= sizeof(buff->pkt)) {		buff = get_trans_buf();		if (buff == NULL) {			msyslog(LOG_ERR, "No more transmit buffers left - data discarded");			FreeHeap(lpo, "io_completion_port_sendto");			return ERROR_OUTOFMEMORY;		}		memcpy(&buff->pkt, pkt, len);		buff->wsabuf.buf = buff->pkt;		buff->wsabuf.len = len;		AddrLen = sizeof(struct sockaddr_in);		lpo->request_type = SOCK_SEND;		lpo->trans_buf = buff;		Result = WSASendTo(inter->fd, &buff->wsabuf, 1, &BytesSent, Flags, (struct sockaddr *) dest, AddrLen, (LPOVERLAPPED) lpo, NULL);		if(Result == SOCKET_ERROR)		{			errval = WSAGetLastError();			switch (errval) {			case NO_ERROR :			case WSA_IO_INCOMPLETE :			case WSA_WAIT_IO_COMPLETION :			case WSA_IO_PENDING :				Result = ERROR_SUCCESS;				break ;			/*			 * Something bad happened			 */			default :				netsyslog(LOG_ERR, "WSASendTo - error sending message: %m");				free_trans_buf(buff);				FreeHeap(lpo, "io_completion_port_sendto");				break;			}		}#ifdef DEBUG		if (debug > 3)			printf("WSASendTo - %d bytes to %s : %d\n", len, stoa(dest), Result);#endif		return (Result);	}	else {#ifdef DEBUG		if (debug) printf("Packet too large: %d Bytes\n", len);#endif		return ERROR_INSUFFICIENT_BUFFER;	}}/* * Async IO Write */DWORD	io_completion_port_write(	HANDLE fd,		char *pkt,		int len){	DWORD errval;	transmitbuf_t *buff = NULL;	DWORD lpNumberOfBytesWritten;	DWORD Result = ERROR_INSUFFICIENT_BUFFER;	IoCompletionInfo *lpo;	lpo = (IoCompletionInfo *) GetHeapAlloc("io_completion_port_write");	if (lpo == NULL)		return ERROR_OUTOFMEMORY;	if (len <= sizeof(buff->pkt)) {		buff = get_trans_buf();		if (buff == NULL) {			msyslog(LOG_ERR, "No more transmit buffers left - data discarded");			FreeHeap(lpo, "io_completion_port_write");		}		lpo->request_type = CLOCK_WRITE;		lpo->trans_buf = buff;		memcpy(&buff->pkt, pkt, len);		Result = WriteFile(fd, buff->pkt, len, &lpNumberOfBytesWritten, (LPOVERLAPPED) lpo);		if(Result == SOCKET_ERROR)		{			errval = WSAGetLastError();			switch (errval) {			case NO_ERROR :			case WSA_IO_INCOMPLETE :			case WSA_WAIT_IO_COMPLETION :			case WSA_IO_PENDING :				Result = ERROR_SUCCESS;				break ;			default :				netsyslog(LOG_ERR, "WriteFile - error sending message: %m");				free_trans_buf(buff);				FreeHeap(lpo, "io_completion_port_write");				break;			}		}#ifdef DEBUG			if (debug > 2) {				printf("WriteFile - %d bytes %d\n", len, Result);			}#endif			if (Result) return len;	}	else {#ifdef DEBUG		if (debug) printf("Packet too large: %d Bytes\n", len);#endif	}	return Result;}/* * GetReceivedBuffers * Note that this is in effect the main loop for processing requests * both send and receive. This should be reimplemented */int GetReceivedBuffers(){	isc_boolean_t have_packet = ISC_FALSE;	while (!have_packet) {		DWORD Index = WaitForMultipleObjects(MAXHANDLES, WaitHandles, FALSE, INFINITE);		switch (Index) {		case WAIT_OBJECT_0 + 0 : /* Io event */# ifdef DEBUG			if ( debug > 3 )			{				printf( "IoEvent occurred\n" );			}# endif			have_packet = ISC_TRUE;			break;		case WAIT_OBJECT_0 + 1 : /* exit request */			exit(0);			break;		case WAIT_OBJECT_0 + 2 : /* timer */			timer();			break;		case WAIT_IO_COMPLETION : /* loop */		case WAIT_TIMEOUT :			break;		case WAIT_FAILED:			msyslog(LOG_ERR, "ntpd: WaitForMultipleObjects Failed: Error: %m");			break;			/* For now do nothing if not expected */		default:			break;								} /* switch */	}	return (full_recvbuffs());	/* get received buffers */}#else  static int NonEmptyCompilationUnit;#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -