transparent: workaround old glibc bug on RHEL7
it's been reported[0] that RHEL7 fails to properly set the length parameter of the getsockname() call to the length of the required struct sockaddr type, and always returns the length passed if it is big enough. the SOCKADDR_UNION_* macros originate from my microsocks[1] project, and facilitate handling of the sockaddr mess without nasty casts. [0]: https://github.com/tinyproxy/tinyproxy/issues/45#issuecomment-694594990 [1]: https://github.com/rofl0r/microsocks
This commit is contained in:
		
							parent
							
								
									d4ef2cfa62
								
							
						
					
					
						commit
						c74fe57262
					
				
							
								
								
									
										14
									
								
								src/sock.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/sock.h
									
									
									
									
									
								
							@ -31,6 +31,20 @@
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "sblist.h"
 | 
			
		||||
 | 
			
		||||
#define SOCKADDR_UNION_AF(PTR) (PTR)->v4.sin_family
 | 
			
		||||
 | 
			
		||||
#define SOCKADDR_UNION_LENGTH(PTR) ( \
 | 
			
		||||
	( SOCKADDR_UNION_AF(PTR) == AF_INET  ) ? sizeof((PTR)->v4) : ( \
 | 
			
		||||
	( SOCKADDR_UNION_AF(PTR) == AF_INET6 ) ? sizeof((PTR)->v6) : 0 ) )
 | 
			
		||||
 | 
			
		||||
#define SOCKADDR_UNION_ADDRESS(PTR) ( \
 | 
			
		||||
	( SOCKADDR_UNION_AF(PTR) == AF_INET  ) ? (void*) &(PTR)->v4.sin_addr  : ( \
 | 
			
		||||
	( SOCKADDR_UNION_AF(PTR) == AF_INET6 ) ? (void*) &(PTR)->v6.sin6_addr : (void*) 0 ) )
 | 
			
		||||
 | 
			
		||||
#define SOCKADDR_UNION_PORT(PTR) ( \
 | 
			
		||||
	( SOCKADDR_UNION_AF(PTR) == AF_INET  ) ? (PTR)->v4.sin_port  : ( \
 | 
			
		||||
	( SOCKADDR_UNION_AF(PTR) == AF_INET6 ) ? (PTR)->v6.sin6_port : 0 ) )
 | 
			
		||||
 | 
			
		||||
union sockaddr_union {
 | 
			
		||||
        struct sockaddr_in  v4;
 | 
			
		||||
        struct sockaddr_in6 v6;
 | 
			
		||||
 | 
			
		||||
@ -83,16 +83,14 @@ do_transparent_proxy (struct conn_s *connptr, orderedmap hashofheaders,
 | 
			
		||||
                        return 0;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                af = length == sizeof(dest_addr.v4) ? AF_INET : AF_INET6;
 | 
			
		||||
                if (af == AF_INET) dest_inaddr = &dest_addr.v4.sin_addr;
 | 
			
		||||
                else dest_inaddr = &dest_addr.v6.sin6_addr;
 | 
			
		||||
                af = SOCKADDR_UNION_AF(&dest_addr);
 | 
			
		||||
                dest_inaddr = SOCKADDR_UNION_ADDRESS(&dest_addr);
 | 
			
		||||
 | 
			
		||||
                if (!inet_ntop(af, dest_inaddr, namebuf, sizeof namebuf))
 | 
			
		||||
                        goto addr_err;
 | 
			
		||||
 | 
			
		||||
                request->host = safestrdup (namebuf);
 | 
			
		||||
                request->port = ntohs (af == AF_INET ? dest_addr.v4.sin_port
 | 
			
		||||
                                       : dest_addr.v6.sin6_port);
 | 
			
		||||
                request->port = ntohs (SOCKADDR_UNION_PORT(&dest_addr));
 | 
			
		||||
 | 
			
		||||
                request->path = (char *) safemalloc (ulen + 1);
 | 
			
		||||
                strlcpy (request->path, *url, ulen + 1);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user