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

📄 socket.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
			goto done;		}		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, 				  "startio_recv: recvmsg(%d) %d bytes, "				  "err %d/%s",				   sock->fd, *nbytes, *recv_errno, strbuf);		}		status = completeio_recv(sock, dev, msghdr,					 *nbytes, *recv_errno);		goto done;	}	dev->result = ISC_R_SUCCESS;	status = DOIO_SOFT;done:	return (status);}/* * 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. */static intcompleteio_send(isc_socket_t *sock, isc_socketevent_t *dev,		struct msghdr *messagehdr, int cc, int send_errno){	char addrbuf[ISC_SOCKADDR_FORMATSIZE];	char strbuf[ISC_STRERRORSIZE];	if(send_errno != 0) {		if (SOFT_ERROR(send_errno))			return (DOIO_SOFT);#define SOFT_OR_HARD(_system, _isc) \	if (send_errno == _system) { \		if (sock->connected) { \			dev->result = _isc; \			return (DOIO_HARD); \		} \		return (DOIO_SOFT); \	}#define ALWAYS_HARD(_system, _isc) \	if (send_errno == _system) { \		dev->result = _isc; \		return (DOIO_HARD); \	}		SOFT_OR_HARD(WSAEACCES, ISC_R_NOPERM);		SOFT_OR_HARD(WSAEAFNOSUPPORT, ISC_R_ADDRNOTAVAIL);		SOFT_OR_HARD(WSAECONNREFUSED, ISC_R_CONNREFUSED);		SOFT_OR_HARD(WSAENOTCONN, ISC_R_CONNREFUSED);		SOFT_OR_HARD(WSAECONNRESET, ISC_R_CONNECTIONRESET);		SOFT_OR_HARD(WSAECONNABORTED, ISC_R_CONNECTIONRESET);		SOFT_OR_HARD(WSAENETRESET, 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(WSAEADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL);		ALWAYS_HARD(WSAEHOSTUNREACH, ISC_R_HOSTUNREACH);		ALWAYS_HARD(WSAEHOSTDOWN, ISC_R_HOSTUNREACH);		ALWAYS_HARD(WSAENETUNREACH, ISC_R_NETUNREACH);		ALWAYS_HARD(WSAENOBUFS, ISC_R_NORESOURCES);		ALWAYS_HARD(EPERM, ISC_R_HOSTUNREACH);		ALWAYS_HARD(EPIPE, ISC_R_NOTCONNECTED);#undef SOFT_OR_HARD#undef ALWAYS_HARD		/*		 * The other error types depend on whether or not the		 * socket is UDP or TCP.  If it is UDP, some errors		 * that we expect to be fatal under TCP are merely		 * annoying, and are really soft errors.		 *		 * However, these soft errors are still returned as		 * a status.		 */		isc_sockaddr_format(&dev->address, addrbuf, sizeof(addrbuf));		isc__strerror(send_errno, strbuf, sizeof(strbuf));		UNEXPECTED_ERROR(__FILE__, __LINE__, "completeio_send: %s: %s",				 addrbuf, strbuf);		dev->result = isc__errno2result(send_errno);	return (DOIO_HARD);	}	/*	 * If we write less than we expected, update counters, poke.	 */	dev->n += cc;	if ((size_t)cc != sock->totalBytes)		return (DOIO_SOFT);	/*	 * Exactly what we wanted to write.  We're done with this	 * entry.  Post its completion event.	 */	dev->result = ISC_R_SUCCESS;	return (DOIO_SUCCESS);}static intstartio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,	     int *send_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_SEND;	lpo->dev = dev;	msghdr = &lpo->messagehdr;	memset(msghdr, 0, sizeof(struct msghdr));	build_msghdr_send(sock, dev, msghdr, cmsg, sock->iov,			&(sock->totalBytes));	*nbytes = internal_sendmsg(sock, lpo, msghdr, 0, send_errno);	if (*nbytes < 0) {		if (SOFT_ERROR(*send_errno)) {			status = DOIO_SOFT;			goto done;		}		if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) {			isc__strerror(*send_errno, strbuf, sizeof(strbuf));			socket_log(sock, NULL, IOEVENT,				   isc_msgcat, ISC_MSGSET_SOCKET,				   ISC_MSG_INTERNALSEND, 				   "startio_send: internal_sendmsg(%d) %d "				   "bytes, err %d/%s",				   sock->fd, *nbytes, *send_errno, strbuf);		}		status = completeio_send(sock, dev, msghdr,					 *nbytes, *send_errno);		goto done;	}	dev->result = ISC_R_SUCCESS;	status = DOIO_SOFT;done:	return (status);}/* * Kill. * * Caller must ensure that the socket is not locked and no external * references exist. */static voiddestroy_socket(isc_socket_t **sockp) {	isc_socket_t *sock = *sockp;	isc_socketmgr_t *manager = sock->manager;	isc_boolean_t dofree = ISC_TRUE;	REQUIRE(sock != NULL);	socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET,		   ISC_MSG_DESTROYING, "destroying socket %d", sock->fd);	INSIST(ISC_LIST_EMPTY(sock->accept_list));	INSIST(ISC_LIST_EMPTY(sock->recv_list));	INSIST(ISC_LIST_EMPTY(sock->send_list));	INSIST(sock->connect_ev == NULL);	LOCK(&manager->lock);	LOCK(&sock->lock);	socket_close(sock);	if (sock->pending_recv != 0 || sock->pending_send != 0) {		dofree = ISC_FALSE;		sock->pending_free = 1;	}	ISC_LIST_UNLINK(manager->socklist, sock, link);	UNLOCK(&sock->lock);	if (ISC_LIST_EMPTY(manager->socklist))		SIGNAL(&manager->shutdown_ok);	/*	 * XXX should reset manager->maxfd here	 */	UNLOCK(&manager->lock);	if (dofree)		free_socket(sockp);}static isc_result_tallocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,		isc_socket_t **socketp) {	isc_socket_t *sock;	isc_result_t ret;	sock = isc_mem_get(manager->mctx, sizeof(*sock));	if (sock == NULL)		return (ISC_R_NOMEMORY);	ret = ISC_R_UNEXPECTED;	sock->magic = 0;	sock->references = 0;	sock->manager = manager;	sock->type = type;	sock->fd = INVALID_SOCKET;	ISC_LINK_INIT(sock, link);	/*	 * set up list of readers and writers to be initially empty	 */	ISC_LIST_INIT(sock->recv_list);	ISC_LIST_INIT(sock->send_list);	ISC_LIST_INIT(sock->accept_list);	sock->connect_ev = NULL;	sock->pending_accept = 0;	sock->pending_close = 0;	sock->pending_recv = 0;	sock->pending_send = 0;	sock->pending_free = 0;	sock->iocp = 0;	sock->listener = 0;	sock->connected = 0;	sock->connecting = 0;	sock->bound = 0;	sock->hEvent = NULL;	sock->hAlert = NULL;	sock->evthread_id = 0;	sock->wait_type = 0;	/*	 * initialize the lock	 */	if (isc_mutex_init(&sock->lock) != ISC_R_SUCCESS) {		sock->magic = 0;		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "isc_mutex_init() %s",				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,						ISC_MSG_FAILED, "failed"));		ret = ISC_R_UNEXPECTED;		goto error;	}	/*	 * Initialize readable and writable events	 */	ISC_EVENT_INIT(&sock->readable_ev, sizeof(intev_t),		       ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTR,		       NULL, sock, sock, NULL, NULL);	ISC_EVENT_INIT(&sock->writable_ev, sizeof(intev_t),		       ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTW,		       NULL, sock, sock, NULL, NULL);	sock->magic = SOCKET_MAGIC;	*socketp = sock;	return (ISC_R_SUCCESS); error:	isc_mem_put(manager->mctx, sock, sizeof(*sock));	return (ret);}/* * This event requires that the various lists be empty, that the reference * count be 1, and that the magic number is valid.  The other socket bits, * like the lock, must be initialized as well.  The fd associated must be * marked as closed, by setting it to INVALID_SOCKET on close, or this * routine will also close the socket. */static voidfree_socket(isc_socket_t **socketp) {	isc_socket_t *sock = *socketp;	INSIST(sock->references == 0);	INSIST(VALID_SOCKET(sock));	INSIST(!sock->connecting);	INSIST(!sock->pending_accept);	INSIST(ISC_LIST_EMPTY(sock->recv_list));	INSIST(ISC_LIST_EMPTY(sock->send_list));	INSIST(ISC_LIST_EMPTY(sock->accept_list));	INSIST(!ISC_LINK_LINKED(sock, link));	sock->magic = 0;	DESTROYLOCK(&sock->lock);	isc_mem_put(sock->manager->mctx, sock, sizeof(*sock));	*socketp = NULL;}/* * Create a new 'type' socket managed by 'manager'.  Events * will be posted to 'task' and when dispatched 'action' will be * called with 'arg' as the arg value.  The new socket is returned * in 'socketp'. */isc_result_tisc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,		  isc_socket_t **socketp) {	isc_socket_t *sock = NULL;	isc_result_t result;#if defined(USE_CMSG) || defined(SO_BSDCOMPAT)	int on = 1;#endif	int socket_errno;	char strbuf[ISC_STRERRORSIZE];	REQUIRE(VALID_MANAGER(manager));	REQUIRE(socketp != NULL && *socketp == NULL);	result = allocate_socket(manager, type, &sock);	if (result != ISC_R_SUCCESS)		return (result);	sock->pf = pf;	switch (type) {	case isc_sockettype_udp:		sock->fd = socket(pf, SOCK_DGRAM, IPPROTO_UDP);		if (sock->fd != INVALID_SOCKET) {			result = connection_reset_fix(sock->fd);			if (result != ISC_R_SUCCESS) {				closesocket(sock->fd);				free_socket(&sock);				return (result);			}		}		break;	case isc_sockettype_tcp:		sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP);		break;	}		if (sock->fd == INVALID_SOCKET) {		socket_errno = WSAGetLastError();		free_socket(&sock);		switch (socket_errno) {		case WSAEMFILE:		case WSAENOBUFS:			return (ISC_R_NORESOURCES);		case WSAEPROTONOSUPPORT:		case WSAEPFNOSUPPORT:		case WSAEAFNOSUPPORT:			return (ISC_R_FAMILYNOSUPPORT);		default:			isc__strerror(socket_errno, strbuf, sizeof(strbuf));			UNEXPECTED_ERROR(__FILE__, __LINE__,					 "socket() %s: %s",					 isc_msgcat_get(isc_msgcat,							ISC_MSGSET_GENERAL,							ISC_MSG_FAILED,							"failed"),					 strbuf);			return (ISC_R_UNEXPECTED);		}	}	result = make_nonblock(sock->fd);	if (result != ISC_R_SUCCESS) {		free_socket(&sock);		return (result);	}#if defined(USE_CMSG)	if (type == isc_sockettype_udp) {#if defined(ISC_PLATFORM_HAVEIPV6)#ifdef IPV6_RECVPKTINFO		/* 2292bis */		if ((pf == AF_INET6)		    && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,				   (void *)&on, sizeof(on)) < 0)) {			isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));			UNEXPECTED_ERROR(__FILE__, __LINE__,					 "setsockopt(%d, IPV6_RECVPKTINFO) "					 "%s: %s", sock->fd,					 isc_msgcat_get(isc_msgcat,							ISC_MSGSET_GENERAL,							ISC_MSG_FAILED,							"failed"),					 strbuf);		}#else		/* 2292 */		if ((pf == AF_INET6)		    && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO,				   (void *)&on, sizeof(on)) < 0)) {			isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));			UNEXPECTED_ERROR(__FILE__, __LINE__,					 "setsockopt(%d, IPV6_PKTINFO) %s: %s",					 sock->fd,					 isc_msgcat_get(isc_msgcat,							ISC_MSGSET_GENERAL,							ISC_MSG_FAILED,							"failed"),					 strbuf);		}#endif /* IPV6_RECVPKTINFO */#ifdef IPV6_USE_MIN_MTU        /*2292bis, not too common yet*/		/* use minimum MTU */		if (pf == AF_INET6) {			(void)setsockopt(sock->fd, IPPROTO_IPV6,					 IPV6_USE_MIN_MTU,					 (void *)&on, sizeof(on));		}#endif#endif /* ISC_PLATFORM_HAVEIPV6 */	}#endif /* USE_CMSG */	sock->references = 1;	*socketp = sock;	LOCK(&manager->lock);	/*	 * Note we don't have to lock the socket like we normally would because	 * there are no external references to it yet.	 */	ISC_LIST_APPEND(manager->socklist, sock, link);	UNLOCK(&manager->lock);	socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET,		   ISC_MSG_CREATED, "created %u", sock->fd);	return (ISC_R_SUCCESS);}/* * Attach to a socket.  Caller must explicitly detach when it is done. */voidisc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {	REQUIRE(VALID_SOCKET(sock));	REQUIRE(socketp != NULL && *socketp == NULL);	LOCK(&sock->lock);	sock->references++;	UNLOCK(&sock->lock);	*socketp = sock;}/* * Dereference a socket.  If this is the last reference to it, clean things * up by destroying the socket. */voidisc_socket_detach(isc_socket_t **socketp) {	isc_socket_t *sock;	isc_boolean_t kill_socket = ISC_FALSE;	REQUIRE(socketp != NULL);	sock = *socketp;	REQUIRE(VALID_SOCKET(sock));	LOCK(&sock->lock);	REQUIRE(sock->references > 0);	sock->references--;	if (sock->references == 0)		kill_socket = ISC_TRUE;	UNLOCK(&sock->lock);	if (kill_socket)		destroy_socket(&sock);	*socketp = NULL;}

⌨️ 快捷键说明

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