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

📄 socket_wrapper.c

📁 samba服务器!
💻 C
📖 第 1 页 / 共 3 页
字号:
		break;	case AF_UNIX:		return real_socket(family, type, protocol);	default:		errno = EAFNOSUPPORT;		return -1;	}	switch (type) {	case SOCK_STREAM:		break;	case SOCK_DGRAM:		break;	default:		errno = EPROTONOSUPPORT;		return -1;	}	switch (protocol) {	case 0:		break;	default:		errno = EPROTONOSUPPORT;		return -1;	}	fd = real_socket(AF_UNIX, type, 0);	if (fd == -1) return -1;	si = (struct socket_info *)calloc(1, sizeof(struct socket_info));	si->family = family;	si->type = type;	si->protocol = protocol;	si->fd = fd;	SWRAP_DLIST_ADD(sockets, si);	return si->fd;}_PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen){	struct socket_info *parent_si, *child_si;	int fd;	struct sockaddr_un un_addr;	socklen_t un_addrlen = sizeof(un_addr);	struct sockaddr_un un_my_addr;	socklen_t un_my_addrlen = sizeof(un_my_addr);	struct sockaddr my_addr;	socklen_t my_addrlen = sizeof(my_addr);	int ret;	parent_si = find_socket_info(s);	if (!parent_si) {		return real_accept(s, addr, addrlen);	}	memset(&un_addr, 0, sizeof(un_addr));	memset(&un_my_addr, 0, sizeof(un_my_addr));	memset(&my_addr, 0, sizeof(my_addr));	ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen);	if (ret == -1) return ret;	fd = ret;	ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,				       parent_si->family, addr, addrlen);	if (ret == -1) {		close(fd);		return ret;	}	child_si = (struct socket_info *)malloc(sizeof(struct socket_info));	memset(child_si, 0, sizeof(*child_si));	child_si->fd = fd;	child_si->family = parent_si->family;	child_si->type = parent_si->type;	child_si->protocol = parent_si->protocol;	child_si->bound = 1;	child_si->is_server = 1;	ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen);	if (ret == -1) {		free(child_si);		close(fd);		return ret;	}	ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,				       child_si->family, &my_addr, &my_addrlen);	if (ret == -1) {		free(child_si);		close(fd);		return ret;	}	child_si->myname_len = my_addrlen;	child_si->myname = sockaddr_dup(&my_addr, my_addrlen);	child_si->peername_len = *addrlen;	child_si->peername = sockaddr_dup(addr, *addrlen);	SWRAP_DLIST_ADD(sockets, child_si);	swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);	swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);	swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);	return fd;}static int autobind_start_init;static int autobind_start;/* using sendto() or connect() on an unbound socket would give the   recipient no way to reply, as unlike UDP and TCP, a unix domain   socket can't auto-assign emphemeral port numbers, so we need to   assign it here */static int swrap_auto_bind(struct socket_info *si){	struct sockaddr_un un_addr;	struct sockaddr_in in;	int i;	char type;	int ret;	int port;	struct stat st;	if (autobind_start_init != 1) {		autobind_start_init = 1;		autobind_start = getpid();		autobind_start %= 50000;		autobind_start += 10000;	}	un_addr.sun_family = AF_UNIX;	switch (si->type) {	case SOCK_STREAM:		type = SOCKET_TYPE_CHAR_TCP;		break;	case SOCK_DGRAM:		type = SOCKET_TYPE_CHAR_UDP;		break;	default:		errno = ESOCKTNOSUPPORT;		return -1;	}	if (autobind_start > 60000) {		autobind_start = 10000;	}	for (i=0;i<1000;i++) {		port = autobind_start + i;		snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), 			 "%s/"SOCKET_FORMAT, socket_wrapper_dir(),			 type, socket_wrapper_default_iface(), port);		if (stat(un_addr.sun_path, &st) == 0) continue;				ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr));		if (ret == -1) return ret;		si->tmp_path = strdup(un_addr.sun_path);		si->bound = 1;		autobind_start = port + 1;		break;	}	if (i == 1000) {		errno = ENFILE;		return -1;	}	memset(&in, 0, sizeof(in));	in.sin_family = AF_INET;	in.sin_port   = htons(port);	in.sin_addr.s_addr = htonl(127<<24 | socket_wrapper_default_iface());		si->myname_len = sizeof(in);	si->myname = sockaddr_dup(&in, si->myname_len);	return 0;}_PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen){	int ret;	struct sockaddr_un un_addr;	struct socket_info *si = find_socket_info(s);	if (!si) {		return real_connect(s, serv_addr, addrlen);	}	if (si->bound == 0) {		ret = swrap_auto_bind(si);		if (ret == -1) return -1;	}	ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL);	if (ret == -1) return -1;	swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);	ret = real_connect(s, (struct sockaddr *)&un_addr, 			   sizeof(struct sockaddr_un));	/* to give better errors */	if (ret == -1 && errno == ENOENT) {		errno = EHOSTUNREACH;	}	if (ret == 0) {		si->peername_len = addrlen;		si->peername = sockaddr_dup(serv_addr, addrlen);		swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);		swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);	} else {		swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);	}	return ret;}_PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen){	int ret;	struct sockaddr_un un_addr;	struct socket_info *si = find_socket_info(s);	if (!si) {		return real_bind(s, myaddr, addrlen);	}	si->myname_len = addrlen;	si->myname = sockaddr_dup(myaddr, addrlen);	ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast);	if (ret == -1) return -1;	unlink(un_addr.sun_path);	ret = real_bind(s, (struct sockaddr *)&un_addr,			sizeof(struct sockaddr_un));	if (ret == 0) {		si->bound = 1;	}	return ret;}_PUBLIC_ int swrap_listen(int s, int backlog){	int ret;	struct socket_info *si = find_socket_info(s);	if (!si) {		return real_listen(s, backlog);	}	ret = real_listen(s, backlog);	return ret;}_PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen){	struct socket_info *si = find_socket_info(s);	if (!si) {		return real_getpeername(s, name, addrlen);	}	if (!si->peername)	{		errno = ENOTCONN;		return -1;	}	memcpy(name, si->peername, si->peername_len);	*addrlen = si->peername_len;	return 0;}_PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen){	struct socket_info *si = find_socket_info(s);	if (!si) {		return real_getsockname(s, name, addrlen);	}	memcpy(name, si->myname, si->myname_len);	*addrlen = si->myname_len;	return 0;}_PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen){	struct socket_info *si = find_socket_info(s);	if (!si) {		return real_getsockopt(s, level, optname, optval, optlen);	}	if (level == SOL_SOCKET) {		return real_getsockopt(s, level, optname, optval, optlen);	} 	errno = ENOPROTOOPT;	return -1;}_PUBLIC_ int swrap_setsockopt(int s, int  level,  int  optname,  const  void  *optval, socklen_t optlen){	struct socket_info *si = find_socket_info(s);	if (!si) {		return real_setsockopt(s, level, optname, optval, optlen);	}	if (level == SOL_SOCKET) {		return real_setsockopt(s, level, optname, optval, optlen);	}	switch (si->family) {	case AF_INET:		return 0;	default:		errno = ENOPROTOOPT;		return -1;	}}_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen){	struct sockaddr_un un_addr;	socklen_t un_addrlen = sizeof(un_addr);	int ret;	struct socket_info *si = find_socket_info(s);	if (!si) {		return real_recvfrom(s, buf, len, flags, from, fromlen);	}	/* irix 6.4 forgets to null terminate the sun_path string :-( */	memset(&un_addr, 0, sizeof(un_addr));	ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen);	if (ret == -1) 		return ret;	if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,				     si->family, from, fromlen) == -1) {		return -1;	}	swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);	return ret;}_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen){	struct sockaddr_un un_addr;	int ret;	struct socket_info *si = find_socket_info(s);	int bcast = 0;	if (!si) {		return real_sendto(s, buf, len, flags, to, tolen);	}	if (si->bound == 0) {		ret = swrap_auto_bind(si);		if (ret == -1) return -1;	}	ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast);	if (ret == -1) return -1;	if (bcast) {		struct stat st;		unsigned int iface;		unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);		char type;		type = SOCKET_TYPE_CHAR_UDP;		for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {			snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, 				 socket_wrapper_dir(), type, iface, prt);			if (stat(un_addr.sun_path, &st) != 0) continue;			/* ignore the any errors in broadcast sends */			real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));		}		swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);		return len;	}	ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));	/* to give better errors */	if (ret == -1 && errno == ENOENT) {		errno = EHOSTUNREACH;	}	if (ret == -1) {		swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);		swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);	} else {		swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret);	}	return ret;}_PUBLIC_ int swrap_ioctl(int s, int r, void *p){	int ret;	struct socket_info *si = find_socket_info(s);	int value;	if (!si) {		return real_ioctl(s, r, p);	}	ret = real_ioctl(s, r, p);	switch (r) {	case FIONREAD:		value = *((int *)p);		if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {			swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);		} else if (value == 0) { /* END OF FILE */			swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);		}		break;	}	return ret;}_PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags){	int ret;	struct socket_info *si = find_socket_info(s);	if (!si) {		return real_recv(s, buf, len, flags);	}	ret = real_recv(s, buf, len, flags);	if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {		swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);	} else if (ret == 0) { /* END OF FILE */		swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);	} else {		swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);	}	return ret;}_PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags){	int ret;	struct socket_info *si = find_socket_info(s);	if (!si) {		return real_send(s, buf, len, flags);	}	ret = real_send(s, buf, len, flags);	if (ret == -1) {		swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);		swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);	} else {		swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);	}	return ret;}_PUBLIC_ int swrap_close(int fd){	struct socket_info *si = find_socket_info(fd);	int ret;	if (!si) {		return real_close(fd);	}	SWRAP_DLIST_REMOVE(sockets, si);	if (si->myname && si->peername) {		swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);	}	ret = real_close(fd);	if (si->myname && si->peername) {		swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);		swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);	}	if (si->path) free(si->path);	if (si->myname) free(si->myname);	if (si->peername) free(si->peername);	if (si->tmp_path) {		unlink(si->tmp_path);		free(si->tmp_path);	}	free(si);	return ret;}

⌨️ 快捷键说明

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