mirror of
				https://github.com/3proxy/3proxy.git
				synced 2025-11-04 15:52:39 +08:00 
			
		
		
		
	Add check for socket errors after poll
This is to return an error when a connection refused packet is returned from the remote host. As `connect` is called in a non-blocking mode, things like refused connections don't get caught. The subsequent `poll` will just block until the socket is ready, and as it's a file operator it doesn't know/care about refused network connections. Therefore we need to add a check for socket errors after the poll, which should be enough to catch any connection errors.
This commit is contained in:
		
							parent
							
								
									6387bed4f2
								
							
						
					
					
						commit
						9b949a8b4a
					
				
							
								
								
									
										24
									
								
								src/common.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								src/common.c
									
									
									
									
									
								
							@ -475,22 +475,36 @@ int parseconnusername(char *username, struct clientparam *param, int extpasswd,
 | 
			
		||||
 | 
			
		||||
int connectwithpoll(struct clientparam *param, SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to){
 | 
			
		||||
		struct pollfd fds[1];
 | 
			
		||||
		int err;
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		unsigned long ul = 1;
 | 
			
		||||
		ioctlsocket(sock, FIONBIO, &ul);
 | 
			
		||||
#else
 | 
			
		||||
		fcntl(sock,F_SETFL, O_NONBLOCK | fcntl(sock,F_GETFL));
 | 
			
		||||
#endif
 | 
			
		||||
		if(param?param->srv->so._connect(param->sostate, sock,sa,size) : so._connect(so.state, sock,sa,size)) {
 | 
			
		||||
		err = param ? param->srv->so._connect(param->sostate, sock,sa,size) : so._connect(so.state, sock,sa,size);
 | 
			
		||||
		if(err) {
 | 
			
		||||
			if(errno != EAGAIN && errno != EINPROGRESS) return (13);
 | 
			
		||||
		}
 | 
			
		||||
		if(!errno) return 0;
 | 
			
		||||
	        memset(fds, 0, sizeof(fds));
 | 
			
		||||
	        fds[0].fd = sock;
 | 
			
		||||
	        fds[0].events = POLLOUT|POLLIN;
 | 
			
		||||
		if((param?param->srv->so._poll(param->sostate, fds, 1, to*1000):so._poll(so.state, fds, 1, to*1000)) <= 0 || !(fds[0].revents & POLLOUT)) {
 | 
			
		||||
 | 
			
		||||
		memset(fds, 0, sizeof(fds));
 | 
			
		||||
		fds[0].fd = sock;
 | 
			
		||||
		fds[0].events = POLLOUT|POLLIN;
 | 
			
		||||
 | 
			
		||||
		err = param ? param->srv->so._poll(param->sostate, fds, 1, to*1000) : so._poll(so.state, fds, 1, to*1000);
 | 
			
		||||
		if(err <= 0 || !(fds[0].revents & POLLOUT)) {
 | 
			
		||||
			return (13);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int sock_err;
 | 
			
		||||
		socklen_t len = sizeof(sock_err);
 | 
			
		||||
 | 
			
		||||
		err = param ? param->srv->so._getsockopt(param->sostate, sock, SOL_SOCKET, SO_ERROR, &sock_err, &len) : so._getsockopt(so.state, sock, SOL_SOCKET, SO_ERROR, &sock_err, &len);
 | 
			
		||||
		if(err || sock_err > 0) {
 | 
			
		||||
			return (13);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user