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

📄 socket.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
		return (-1);	else		return (total_bytes);} static voidmanager_log(isc_socketmgr_t *sockmgr, isc_logcategory_t *category,	    isc_logmodule_t *module, int level, const char *fmt, ...){	char msgbuf[2048];	va_list ap;	if (!isc_log_wouldlog(isc_lctx, level))		return;	va_start(ap, fmt);	vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);	va_end(ap);	isc_log_write(isc_lctx, category, module, level,		      "sockmgr %p: %s", sockmgr, msgbuf);}static voidsocket_log(isc_socket_t *sock, isc_sockaddr_t *address,	   isc_logcategory_t *category, isc_logmodule_t *module, int level,	   isc_msgcat_t *msgcat, int msgset, int message,	   const char *fmt, ...) ISC_FORMAT_PRINTF(9, 10);static voidsocket_log(isc_socket_t *sock, isc_sockaddr_t *address,	   isc_logcategory_t *category, isc_logmodule_t *module, int level,	   isc_msgcat_t *msgcat, int msgset, int message,	   const char *fmt, ...){	char msgbuf[2048];	char peerbuf[256];	va_list ap;	if (! isc_log_wouldlog(isc_lctx, level))		return;	va_start(ap, fmt);	vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);	va_end(ap);	if (address == NULL) {		isc_log_iwrite(isc_lctx, category, module, level,			       msgcat, msgset, message,			       "socket %p: %s", sock, msgbuf);	} else {		isc_sockaddr_format(address, peerbuf, sizeof(peerbuf));		isc_log_iwrite(isc_lctx, category, module, level,			       msgcat, msgset, message,			       "socket %p %s: %s", sock, peerbuf, msgbuf);	}}/* * Make an fd SOCKET non-blocking. */static isc_result_tmake_nonblock(SOCKET fd) {	int ret;	unsigned long flags = 1;	char strbuf[ISC_STRERRORSIZE];	/* Set the socket to non-blocking */	ret = ioctlsocket(fd, FIONBIO, &flags);	if (ret == -1) {		isc__strerror(errno, strbuf, sizeof(strbuf));		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "ioctlsocket(%d, FIOBIO, %d): %s",				 fd, flags, strbuf);		return (ISC_R_UNEXPECTED);	}	return (ISC_R_SUCCESS);}/* * Windows 2000 systems incorrectly cause UDP sockets using WASRecvFrom * to not work correctly, returning a WSACONNRESET error when a WSASendTo * fails with an "ICMP port unreachable" response and preventing the * socket from using the WSARecvFrom in subsequent operations. * The function below fixes this, but requires that Windows 2000 * Service Pack 2 or later be installed on the system.  NT 4.0 * systems are not affected by this and work correctly. * See Microsoft Knowledge Base Article Q263823 for details of this. */isc_result_tconnection_reset_fix(SOCKET fd) {	DWORD dwBytesReturned = 0;	BOOL  bNewBehavior = FALSE;	DWORD status;	if(isc_win32os_majorversion() < 5)		return (ISC_R_SUCCESS); /*  NT 4.0 has no problem */	/* disable bad behavior using IOCTL: SIO_UDP_CONNRESET */	status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior,			  sizeof(bNewBehavior), NULL, 0,			  &dwBytesReturned, NULL, NULL);	if (status != SOCKET_ERROR)		return (ISC_R_SUCCESS);	else {		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "WSAIoctl(SIO_UDP_CONNRESET, oldBehaviour) %s",				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,						ISC_MSG_FAILED, "failed"));		return (ISC_R_UNEXPECTED);	}}/* * Construct an iov array and attach it to the msghdr passed in.  This is * the SEND constructor, which will use the used region of the buffer * (if using a buffer list) or will use the internal region (if a single * buffer I/O is requested). * * Nothing can be NULL, and the done event must list at least one buffer * on the buffer linked list for this function to be meaningful. * * If write_countp != NULL, *write_countp will hold the number of bytes * this transaction can send. */static voidbuild_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,		  struct msghdr *msg, char *cmsg,		  WSABUF *iov, size_t *write_countp){	unsigned int iovcount;	isc_buffer_t *buffer;	isc_region_t used;	size_t write_count;	size_t skip_count;	memset(msg, 0, sizeof(*msg));	if (sock->type == isc_sockettype_udp) {		msg->msg_name = (void *)&dev->address.type.sa;		msg->msg_namelen = dev->address.length;	} else {		msg->msg_name = NULL;		msg->msg_namelen = 0;	}	buffer = ISC_LIST_HEAD(dev->bufferlist);	write_count = 0;	iovcount = 0;	/*	 * Single buffer I/O?  Skip what we've done so far in this region.	 */	if (buffer == NULL) {		write_count = dev->region.length - dev->n;		iov[0].buf = (void *)(dev->region.base + dev->n);		iov[0].len = write_count;		iovcount = 1;		goto config;	}	/*	 * Multibuffer I/O.	 * Skip the data in the buffer list that we have already written.	 */	skip_count = dev->n;	while (buffer != NULL) {		REQUIRE(ISC_BUFFER_VALID(buffer));		if (skip_count < isc_buffer_usedlength(buffer))			break;		skip_count -= isc_buffer_usedlength(buffer);		buffer = ISC_LIST_NEXT(buffer, link);	}	while (buffer != NULL) {		INSIST(iovcount < MAXSCATTERGATHER_SEND);		isc_buffer_usedregion(buffer, &used);		if (used.length > 0) {			iov[iovcount].buf = (void *)(used.base							  + skip_count);			iov[iovcount].len = used.length - skip_count;			write_count += (used.length - skip_count);			skip_count = 0;			iovcount++;		}		buffer = ISC_LIST_NEXT(buffer, link);	}	INSIST(skip_count == 0); config:	msg->msg_iov = iov;	msg->msg_iovlen = iovcount;	if (write_countp != NULL)		*write_countp = write_count;}/* * Construct an iov array and attach it to the msghdr passed in.  This is * the RECV constructor, which will use the available region of the buffer * (if using a buffer list) or will use the internal region (if a single * buffer I/O is requested). * * Nothing can be NULL, and the done event must list at least one buffer * on the buffer linked list for this function to be meaningful. * * If read_countp != NULL, *read_countp will hold the number of bytes * this transaction can receive. */static voidbuild_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev,		  struct msghdr *msg, char *cmsg,		  WSABUF *iov, size_t *read_countp){	unsigned int iovcount;	isc_buffer_t *buffer;	isc_region_t available;	size_t read_count;	memset(msg, 0, sizeof(struct msghdr));	if (sock->type == isc_sockettype_udp) {		memset(&dev->address, 0, sizeof(dev->address));		msg->msg_name = (void *)&dev->address.type.sa;		msg->msg_namelen = sizeof(dev->address.type);	} else { /* TCP */		msg->msg_name = NULL;		msg->msg_namelen = 0;		dev->address = sock->address;	}	buffer = ISC_LIST_HEAD(dev->bufferlist);	read_count = 0;	/*	 * Single buffer I/O?  Skip what we've done so far in this region.	 */	if (buffer == NULL) {		read_count = dev->region.length - dev->n;		iov[0].buf = (void *)(dev->region.base + dev->n);		iov[0].len = read_count;		iovcount = 1;	} else {		/*		 * Multibuffer I/O.		 * Skip empty buffers.		 */		while (buffer != NULL) {			REQUIRE(ISC_BUFFER_VALID(buffer));			if (isc_buffer_availablelength(buffer) != 0)				break;			buffer = ISC_LIST_NEXT(buffer, link);		}		iovcount = 0;		while (buffer != NULL) {			INSIST(iovcount < MAXSCATTERGATHER_RECV);			isc_buffer_availableregion(buffer, &available);			if (available.length > 0) {				iov[iovcount].buf = (void *)(available.base);				iov[iovcount].len = available.length;				read_count += available.length;				iovcount++;			}			buffer = ISC_LIST_NEXT(buffer, link);		}	}	/*	 * If needed, set up to receive that one extra byte.  Note that	 * we know there is at least one iov left, since we stole it	 * at the top of this function.	 */	msg->msg_iov = iov;	msg->msg_iovlen = iovcount;	if (read_countp != NULL)		*read_countp = read_count;}static voidset_dev_address(isc_sockaddr_t *address, isc_socket_t *sock,		isc_socketevent_t *dev){	if (sock->type == isc_sockettype_udp) {		if (address != NULL)			dev->address = *address;		else			dev->address = sock->address;	} else if (sock->type == isc_sockettype_tcp) {		INSIST(address == NULL);		dev->address = sock->address;	}}static isc_socketevent_t *allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype,		     isc_taskaction_t action, const void *arg){	isc_socketevent_t *ev;	ev = (isc_socketevent_t *)isc_event_allocate(sock->manager->mctx,						     sock, eventtype,						     action, arg,						     sizeof(*ev));	if (ev == NULL)		return (NULL);	ev->result = ISC_R_UNEXPECTED;	ISC_LINK_INIT(ev, ev_link);	ISC_LIST_INIT(ev->bufferlist);	ev->region.base = NULL;	ev->n = 0;	ev->offset = 0;	ev->attributes = 0;	return (ev);}#if defined(ISC_SOCKET_DEBUG)static voiddump_msg(struct msghdr *msg, isc_socket_t *sock) {	unsigned int i;	printf("MSGHDR %p, Socket #: %u\n", msg, sock->fd);	printf("\tname %p, namelen %d\n", msg->msg_name, msg->msg_namelen);	printf("\tiov %p, iovlen %d\n", msg->msg_iov, msg->msg_iovlen);	for (i = 0; i < (unsigned int)msg->msg_iovlen; i++)		printf("\t\t%d\tbase %p, len %d\n", i,		       msg->msg_iov[i].buf,		       msg->msg_iov[i].len);}#endif#define DOIO_SUCCESS		0	/* i/o ok, event sent */#define DOIO_SOFT		1	/* i/o ok, soft error, no event sent */#define DOIO_HARD		2	/* i/o error, event sent */#define DOIO_EOF		3	/* EOF, no event sent */static intcompleteio_recv(isc_socket_t *sock, isc_socketevent_t *dev,		struct msghdr *messagehdr, int cc, int recv_errno){	size_t actual_count;	isc_buffer_t *buffer;#define SOFT_OR_HARD(_system, _isc) \	if (recv_errno == _system) { \		if (sock->connected) { \			dev->result = _isc; \			return (DOIO_HARD); \		} \		return (DOIO_SOFT); \	}#define ALWAYS_HARD(_system, _isc) \	if (recv_errno == _system) { \		dev->result = _isc; \		return (DOIO_HARD); \	}	if (recv_errno != 0) {		if (SOFT_ERROR(recv_errno))			return (DOIO_SOFT);		SOFT_OR_HARD(WSAECONNREFUSED, ISC_R_CONNREFUSED);		SOFT_OR_HARD(WSAENETUNREACH, ISC_R_NETUNREACH);		SOFT_OR_HARD(WSAEHOSTUNREACH, ISC_R_HOSTUNREACH);		SOFT_OR_HARD(WSAECONNRESET, ISC_R_CONNECTIONRESET);		SOFT_OR_HARD(WSAENETRESET, ISC_R_CONNECTIONRESET);		SOFT_OR_HARD(WSAECONNABORTED, ISC_R_CONNECTIONRESET);		SOFT_OR_HARD(WSAEDISCON, ISC_R_CONNECTIONRESET);		SOFT_OR_HARD(WSAENETDOWN, ISC_R_NETDOWN);		ALWAYS_HARD(ERROR_OPERATION_ABORTED, ISC_R_CONNECTIONRESET);		ALWAYS_HARD(ERROR_PORT_UNREACHABLE, ISC_R_HOSTUNREACH);		ALWAYS_HARD(ERROR_HOST_UNREACHABLE, ISC_R_HOSTUNREACH);		ALWAYS_HARD(ERROR_NETWORK_UNREACHABLE, ISC_R_NETUNREACH);		ALWAYS_HARD(WSAENOBUFS, ISC_R_NORESOURCES);#undef SOFT_OR_HARD#undef ALWAYS_HARD		dev->result = isc__errno2result(recv_errno);		return (DOIO_HARD);	}	/*	 * On TCP, zero length reads indicate EOF, while on	 * UDP, zero length reads are perfectly valid, although	 * strange.	 */	if ((sock->type == isc_sockettype_tcp) && (cc == 0))		return (DOIO_EOF);	if (sock->type == isc_sockettype_udp) {		dev->address.length = messagehdr->msg_namelen;		if (isc_sockaddr_getport(&dev->address) == 0) {			if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) {				socket_log(sock, &dev->address, IOEVENT,					   isc_msgcat, ISC_MSGSET_SOCKET,					   ISC_MSG_ZEROPORT, 					   "dropping source port zero packet");			}			return (DOIO_SOFT);		}	}	socket_log(sock, &dev->address, IOEVENT,		   isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_PKTRECV,		   "packet received correctly");	/*	 * Overflow bit detection.  If we received MORE bytes than we should,	 * this indicates an overflow situation.  Set the flag in the	 * dev entry and adjust how much we read by one.	 */#ifdef ISC_NET_RECVOVERFLOW	if ((sock->type == isc_sockettype_udp) && ((size_t)cc > read_count)) {		dev->attributes |= ISC_SOCKEVENTATTR_TRUNC;		cc--;	}#endif	/*	 * update the buffers (if any) and the i/o count	 */	dev->n += cc;	actual_count = cc;	buffer = ISC_LIST_HEAD(dev->bufferlist);	while (buffer != NULL && actual_count > 0) {		REQUIRE(ISC_BUFFER_VALID(buffer));		if (isc_buffer_availablelength(buffer) <= actual_count) {			actual_count -= isc_buffer_availablelength(buffer);			isc_buffer_add(buffer,				       isc_buffer_availablelength(buffer));		} else {			isc_buffer_add(buffer, actual_count);			actual_count = 0;			break;		}		buffer = ISC_LIST_NEXT(buffer, link);		if (buffer == NULL) {			INSIST(actual_count == 0);		}	}	/*	 * If we read less than we expected, update counters,	 * and let the upper layer handle it.	 */	if (((size_t)cc != sock->totalBytes) && (dev->n < dev->minimum))		return (DOIO_SOFT);	/*	 * Full reads are posted, or partials if partials are ok.	 */	dev->result = ISC_R_SUCCESS;	return (DOIO_SUCCESS);}static intstartio_recv(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,	     int *recv_errno){	char *cmsg = NULL;	char strbuf[ISC_STRERRORSIZE];	IoCompletionInfo *lpo;	int status;	struct msghdr *msghdr;	lpo = (IoCompletionInfo *) HeapAlloc(hHeapHandle,					     HEAP_ZERO_MEMORY,					     sizeof(IoCompletionInfo));	lpo->request_type = SOCKET_RECV;	lpo->dev = dev;	msghdr = &lpo->messagehdr;	memset(msghdr, 0, sizeof(struct msghdr));	build_msghdr_recv(sock, dev, msghdr, cmsg, sock->iov,			  &(sock->totalBytes));#if defined(ISC_SOCKET_DEBUG)	dump_msg(msghdr, sock);#endif	*nbytes = internal_recvmsg(sock, lpo, msghdr, 0, recv_errno);	if (*nbytes < 0) {		if (SOFT_ERROR(*recv_errno)) {			status = DOIO_SOFT;

⌨️ 快捷键说明

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