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

📄 util_sock.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		goto connect_again;	}	if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||			errno == EAGAIN)) {		DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));		close(res);		return -1;	}#ifdef EISCONN	if (ret < 0 && errno == EISCONN) {		errno = 0;		ret = 0;	}#endif	if (ret < 0) {		DEBUG(2,("error connecting to %s:%d (%s)\n",				inet_ntoa(*addr),port,strerror(errno)));		close(res);		return -1;	}	/* set it blocking again */	set_blocking(res,True);	return res;}/**************************************************************************** Create an outgoing TCP socket to any of the addrs. This is for simultaneous connects to port 445 and 139 of a host or even a variety of DC's all of which are equivalent for our purposes.**************************************************************************/BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,			 int timeout, int *fd_index, int *fd){	int i, resulting_index, res;	int *sockets;	BOOL good_connect;	fd_set r_fds, wr_fds;	struct timeval tv;	int maxfd;	int connect_loop = 10000; /* 10 milliseconds */	timeout *= 1000; 	/* convert to microseconds */	sockets = SMB_MALLOC_ARRAY(int, num_addrs);	if (sockets == NULL)		return False;	resulting_index = -1;	for (i=0; i<num_addrs; i++)		sockets[i] = -1;	for (i=0; i<num_addrs; i++) {		sockets[i] = socket(PF_INET, SOCK_STREAM, 0);		if (sockets[i] < 0)			goto done;		set_blocking(sockets[i], False);	} connect_again:	good_connect = False;	for (i=0; i<num_addrs; i++) {		if (sockets[i] == -1)			continue;		if (connect(sockets[i], (struct sockaddr *)&(addrs[i]),			    sizeof(*addrs)) == 0) {			/* Rather unlikely as we are non-blocking, but it			 * might actually happen. */			resulting_index = i;			goto done;		}		if (errno == EINPROGRESS || errno == EALREADY ||		    errno == EAGAIN) {			/* These are the error messages that something is			   progressing. */			good_connect = True;		} else if (errno != 0) {			/* There was a direct error */			close(sockets[i]);			sockets[i] = -1;		}	}	if (!good_connect) {		/* All of the connect's resulted in real error conditions */		goto done;	}	/* Lets see if any of the connect attempts succeeded */	maxfd = 0;	FD_ZERO(&wr_fds);	FD_ZERO(&r_fds);	for (i=0; i<num_addrs; i++) {		if (sockets[i] == -1)			continue;		FD_SET(sockets[i], &wr_fds);		FD_SET(sockets[i], &r_fds);		if (sockets[i]>maxfd)			maxfd = sockets[i];	}	tv.tv_sec = 0;	tv.tv_usec = connect_loop;	res = sys_select(maxfd+1, &r_fds, &wr_fds, NULL, &tv);	if (res < 0)		goto done;	if (res == 0)		goto next_round;	for (i=0; i<num_addrs; i++) {		if (sockets[i] == -1)			continue;		/* Stevens, Network Programming says that if there's a		 * successful connect, the socket is only writable. Upon an		 * error, it's both readable and writable. */		if (FD_ISSET(sockets[i], &r_fds) &&		    FD_ISSET(sockets[i], &wr_fds)) {			/* readable and writable, so it's an error */			close(sockets[i]);			sockets[i] = -1;			continue;		}		if (!FD_ISSET(sockets[i], &r_fds) &&		    FD_ISSET(sockets[i], &wr_fds)) {			/* Only writable, so it's connected */			resulting_index = i;			goto done;		}	} next_round:	timeout -= connect_loop;	if (timeout <= 0)		goto done;	connect_loop *= 1.5;	if (connect_loop > timeout)		connect_loop = timeout;	goto connect_again; done:	for (i=0; i<num_addrs; i++) {		if (i == resulting_index)			continue;		if (sockets[i] >= 0)			close(sockets[i]);	}	if (resulting_index >= 0) {		*fd_index = resulting_index;		*fd = sockets[*fd_index];		set_blocking(*fd, True);	}	free(sockets);	return (resulting_index >= 0);}/**************************************************************************** Open a connected UDP socket to host on port**************************************************************************/int open_udp_socket(const char *host, int port){	int type = SOCK_DGRAM;	struct sockaddr_in sock_out;	int res;	struct in_addr *addr;	addr = interpret_addr2(host);	res = socket(PF_INET, type, 0);	if (res == -1) {		return -1;	}	memset((char *)&sock_out,'\0',sizeof(sock_out));	putip((char *)&sock_out.sin_addr,(char *)addr);	sock_out.sin_port = htons(port);	sock_out.sin_family = PF_INET;	if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {		close(res);		return -1;	}	return res;}/******************************************************************* Matchname - determine if host name matches IP address. Used to confirm a hostname lookup to prevent spoof attacks.******************************************************************/static BOOL matchname(char *remotehost,struct in_addr  addr){	struct hostent *hp;	int     i;		if ((hp = sys_gethostbyname(remotehost)) == 0) {		DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost));		return False;	} 	/*	 * Make sure that gethostbyname() returns the "correct" host name.	 * Unfortunately, gethostbyname("localhost") sometimes yields	 * "localhost.domain". Since the latter host name comes from the	 * local DNS, we just have to trust it (all bets are off if the local	 * DNS is perverted). We always check the address list, though.	 */		if (!strequal(remotehost, hp->h_name)	    && !strequal(remotehost, "localhost")) {		DEBUG(0,("host name/name mismatch: %s != %s\n",			 remotehost, hp->h_name));		return False;	}		/* Look up the host address in the address list we just got. */	for (i = 0; hp->h_addr_list[i]; i++) {		if (memcmp(hp->h_addr_list[i], (char *) & addr, sizeof(addr)) == 0)			return True;	}		/*	 * The host name does not map to the original host address. Perhaps	 * someone has compromised a name server. More likely someone botched	 * it, but that could be dangerous, too.	 */		DEBUG(0,("host name/address mismatch: %s != %s\n",		 inet_ntoa(addr), hp->h_name));	return False;}/******************************************************************* Return the DNS name of the remote end of a socket.******************************************************************/char *get_peer_name(int fd, BOOL force_lookup){	static pstring name_buf;	pstring tmp_name;	static fstring addr_buf;	struct hostent *hp;	struct in_addr addr;	char *p;	/* reverse lookups can be *very* expensive, and in many	   situations won't work because many networks don't link dhcp	   with dns. To avoid the delay we avoid the lookup if	   possible */	if (!lp_hostname_lookups() && (force_lookup == False)) {		return get_peer_addr(fd);	}		p = get_peer_addr(fd);	/* it might be the same as the last one - save some DNS work */	if (strcmp(p, addr_buf) == 0) 		return name_buf;	pstrcpy(name_buf,"UNKNOWN");	if (fd == -1) 		return name_buf;	fstrcpy(addr_buf, p);	addr = *interpret_addr2(p);		/* Look up the remote host name. */	if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) {		DEBUG(1,("Gethostbyaddr failed for %s\n",p));		pstrcpy(name_buf, p);	} else {		pstrcpy(name_buf,(char *)hp->h_name);		if (!matchname(name_buf, addr)) {			DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));			pstrcpy(name_buf,"UNKNOWN");		}	}	/* can't pass the same source and dest strings in when you 	   use --enable-developer or the clobber_region() call will 	   get you */		pstrcpy( tmp_name, name_buf );	alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf));	if (strstr(name_buf,"..")) {		pstrcpy(name_buf, "UNKNOWN");	}	return name_buf;}/******************************************************************* Return the IP addr of the remote end of a socket as a string. ******************************************************************/char *get_peer_addr(int fd){	struct sockaddr sa;	struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);	socklen_t length = sizeof(sa);	static fstring addr_buf;	fstrcpy(addr_buf,"0.0.0.0");	if (fd == -1) {		return addr_buf;	}		if (getpeername(fd, &sa, &length) < 0) {		DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));		return addr_buf;	}		fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));		return addr_buf;}/******************************************************************* Create protected unix domain socket. Some unixes cannot set permissions on a ux-dom-sock, so we have to make sure that the directory contains the protection permissions instead. ******************************************************************/int create_pipe_sock(const char *socket_dir,		     const char *socket_name,		     mode_t dir_perms){#ifdef HAVE_UNIXSOCKET	struct sockaddr_un sunaddr;	struct stat st;	int sock;	mode_t old_umask;	pstring path;        	old_umask = umask(0);        	/* Create the socket directory or reuse the existing one */        	if (lstat(socket_dir, &st) == -1) {		if (errno == ENOENT) {			/* Create directory */			if (mkdir(socket_dir, dir_perms) == -1) {				DEBUG(0, ("error creating socket directory "					"%s: %s\n", socket_dir, 					strerror(errno)));				goto out_umask;			}		} else {			DEBUG(0, ("lstat failed on socket directory %s: %s\n",				socket_dir, strerror(errno)));			goto out_umask;		}	} else {		/* Check ownership and permission on existing directory */		if (!S_ISDIR(st.st_mode)) {			DEBUG(0, ("socket directory %s isn't a directory\n",				socket_dir));			goto out_umask;		}		if ((st.st_uid != sec_initial_uid()) || 				((st.st_mode & 0777) != dir_perms)) {			DEBUG(0, ("invalid permissions on socket directory "				"%s\n", socket_dir));			goto out_umask;		}	}        	/* Create the socket file */        	sock = socket(AF_UNIX, SOCK_STREAM, 0);        	if (sock == -1) {		perror("socket");                goto out_umask;	}        	pstr_sprintf(path, "%s/%s", socket_dir, socket_name);        	unlink(path);	memset(&sunaddr, 0, sizeof(sunaddr));	sunaddr.sun_family = AF_UNIX;	safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1);        	if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {		DEBUG(0, ("bind failed on pipe socket %s: %s\n", path,			strerror(errno)));		goto out_close;	}        	if (listen(sock, 5) == -1) {		DEBUG(0, ("listen failed on pipe socket %s: %s\n", path,			strerror(errno)));		goto out_close;	}        	umask(old_umask);	return sock;out_close:	close(sock);out_umask:	umask(old_umask);	return -1;#else        DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n"));        return -1;#endif /* HAVE_UNIXSOCKET */}

⌨️ 快捷键说明

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