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

📄 socket.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
	UNUSED(dev);#ifdef ISC_NET_BSD44MSGHDR#ifdef MSG_TRUNC	if ((msg->msg_flags & MSG_TRUNC) == MSG_TRUNC)		dev->attributes |= ISC_SOCKEVENTATTR_TRUNC;#endif#ifdef MSG_CTRUNC	if ((msg->msg_flags & MSG_CTRUNC) == MSG_CTRUNC)		dev->attributes |= ISC_SOCKEVENTATTR_CTRUNC;#endif#ifndef USE_CMSG	return;#else	if (msg->msg_controllen == 0U || msg->msg_control == NULL)		return;#ifdef SO_TIMESTAMP	timevalp = NULL;#endif#ifdef ISC_PLATFORM_HAVEIPV6	pktinfop = NULL;#endif	cmsgp = CMSG_FIRSTHDR(msg);	while (cmsgp != NULL) {		socket_log(sock, NULL, TRACE,			   isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_PROCESSCMSG,			   "processing cmsg %p", cmsgp);#ifdef ISC_PLATFORM_HAVEIPV6		if (cmsgp->cmsg_level == IPPROTO_IPV6		    && cmsgp->cmsg_type == IPV6_PKTINFO) {			pktinfop = (struct in6_pktinfo *)CMSG_DATA(cmsgp);			memcpy(&dev->pktinfo, pktinfop,			       sizeof(struct in6_pktinfo));			dev->attributes |= ISC_SOCKEVENTATTR_PKTINFO;			socket_log(sock, NULL, TRACE,				   isc_msgcat, ISC_MSGSET_SOCKET,				   ISC_MSG_IFRECEIVED,				   "interface received on ifindex %u",				   dev->pktinfo.ipi6_ifindex);			if (IN6_IS_ADDR_MULTICAST(&pktinfop->ipi6_addr))				dev->attributes |= ISC_SOCKEVENTATTR_MULTICAST;							goto next;		}#endif#ifdef SO_TIMESTAMP		if (cmsgp->cmsg_level == SOL_SOCKET		    && cmsgp->cmsg_type == SCM_TIMESTAMP) {			timevalp = (struct timeval *)CMSG_DATA(cmsgp);			dev->timestamp.seconds = timevalp->tv_sec;			dev->timestamp.nanoseconds = timevalp->tv_usec * 1000;			dev->attributes |= ISC_SOCKEVENTATTR_TIMESTAMP;			goto next;		}#endif	next:		cmsgp = CMSG_NXTHDR(msg, cmsgp);	}#endif /* USE_CMSG */#endif /* ISC_NET_BSD44MSGHDR */}/* * 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, struct iovec *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].iov_base = (void *)(dev->region.base + dev->n);		iov[0].iov_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].iov_base = (void *)(used.base							  + skip_count);			iov[iovcount].iov_len = used.length - skip_count;			write_count += (used.length - skip_count);			skip_count = 0;			iovcount++;		}		buffer = ISC_LIST_NEXT(buffer, link);	}	INSIST(skip_count == 0U); config:	msg->msg_iov = iov;	msg->msg_iovlen = iovcount;#ifdef ISC_NET_BSD44MSGHDR	msg->msg_control = NULL;	msg->msg_controllen = 0;	msg->msg_flags = 0;#if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIPV6)	if ((sock->type == isc_sockettype_udp)	    && ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0)) {		struct cmsghdr *cmsgp;		struct in6_pktinfo *pktinfop;		socket_log(sock, NULL, TRACE,			   isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_SENDTODATA,			   "sendto pktinfo data, ifindex %u",			   dev->pktinfo.ipi6_ifindex);		msg->msg_controllen = cmsg_space(sizeof(struct in6_pktinfo));		INSIST(msg->msg_controllen <= sock->sendcmsgbuflen);		msg->msg_control = (void *)sock->sendcmsgbuf;		cmsgp = (struct cmsghdr *)sock->sendcmsgbuf;		cmsgp->cmsg_level = IPPROTO_IPV6;		cmsgp->cmsg_type = IPV6_PKTINFO;		cmsgp->cmsg_len = cmsg_len(sizeof(struct in6_pktinfo));		pktinfop = (struct in6_pktinfo *)CMSG_DATA(cmsgp);		memcpy(pktinfop, &dev->pktinfo, sizeof(struct in6_pktinfo));	}#endif /* USE_CMSG && ISC_PLATFORM_HAVEIPV6 */#else /* ISC_NET_BSD44MSGHDR */	msg->msg_accrights = NULL;	msg->msg_accrightslen = 0;#endif /* ISC_NET_BSD44MSGHDR */	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 avialable 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, struct iovec *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);#ifdef ISC_NET_RECVOVERFLOW		/* If needed, steal one iovec for overflow detection. */		maxiov--;#endif	} 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].iov_base = (void *)(dev->region.base + dev->n);		iov[0].iov_len = read_count;		iovcount = 1;		goto config;	}	/*	 * 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].iov_base = (void *)(available.base);			iov[iovcount].iov_len = available.length;			read_count += available.length;			iovcount++;		}		buffer = ISC_LIST_NEXT(buffer, link);	} config:	/*	 * 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.	 */#ifdef ISC_NET_RECVOVERFLOW	if (sock->type == isc_sockettype_udp) {		iov[iovcount].iov_base = (void *)(&sock->overflow);		iov[iovcount].iov_len = 1;		iovcount++;	}#endif	msg->msg_iov = iov;	msg->msg_iovlen = iovcount;#ifdef ISC_NET_BSD44MSGHDR	msg->msg_control = NULL;	msg->msg_controllen = 0;	msg->msg_flags = 0;#if defined(USE_CMSG)	if (sock->type == isc_sockettype_udp) {		msg->msg_control = sock->recvcmsgbuf;		msg->msg_controllen = sock->recvcmsgbuflen;	}#endif /* USE_CMSG */#else /* ISC_NET_BSD44MSGHDR */	msg->msg_accrights = NULL;	msg->msg_accrightslen = 0;#endif /* ISC_NET_BSD44MSGHDR */	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) {	unsigned int i;	printf("MSGHDR %p\n", msg);	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].iov_base,		       msg->msg_iov[i].iov_len);#ifdef ISC_NET_BSD44MSGHDR	printf("\tcontrol %p, controllen %d\n", msg->msg_control,	       msg->msg_controllen);#endif}#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 intdoio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {	int cc;	struct iovec iov[MAXSCATTERGATHER_RECV];	size_t read_count;	size_t actual_count;	struct msghdr msghdr;	isc_buffer_t *buffer;	int recv_errno;	char strbuf[ISC_STRERRORSIZE];	build_msghdr_recv(sock, dev, &msghdr, iov, &read_count);#if defined(ISC_SOCKET_DEBUG)	dump_msg(&msghdr);#endif	cc = recvmsg(sock->fd, &msghdr, 0);	recv_errno = errno;	if (cc < 0) {		if (SOFT_ERROR(recv_errno))			return (DOIO_SOFT);		if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) {			isc__strerror(recv_errno, strbuf, sizeof(strbuf));			socket_log(sock, NULL, IOEVENT,				   isc_msgcat, ISC_MSGSET_SOCKET,				   ISC_MSG_DOIORECV, 				  "doio_recv: recvmsg(%d) %d bytes, err %d/%s",				   sock->fd, cc, recv_errno, strbuf);		}#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); \	}		SOFT_OR_HARD(ECONNREFUSED, ISC_R_CONNREFUSED);		SOFT_OR_HARD(ENETUNREACH, ISC_R_NETUNREACH);		SOFT_OR_HARD(EHOSTUNREACH, ISC_R_HOSTUNREACH);		SOFT_OR_HARD(EHOSTDOWN, ISC_R_HOSTDOWN);		/* HPUX 11.11 can return EADDRNOTAVAIL. */		SOFT_OR_HARD(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL);		ALWAYS_HARD(ENOBUFS, 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 = msghdr.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	/*	 * If there are control messages attached, run through them and pull	 * out the interesting bits.	 */	if (sock->type == isc_sockettype_udp)		process_cmsg(sock, &msghdr, dev);	/*	 * 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 > 0U) {		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 == 0U);		}	}	/*	 * If we read less than we expected, update counters,	 * and let the upper layer poke the descriptor.	 */	if (((size_t)cc != read_count) && (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);}/* * Returns: *	DOIO_SUCCESS	The operation succeeded.  dev->result contains *			ISC_R_SUCCESS. * *	DOIO_HARD	A hard or unexpected I/O error was encountered. *			dev->result contains the appropriate error. * *	DOIO_SOFT	A soft I/O error was encountered.  No senddone *			event was sent.  The operation should be retried. * *	No other return values are possible.

⌨️ 快捷键说明

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