MEDIUM: connection: Upstream SOCKS4 proxy support

Have "socks4" and "check-via-socks4" server keyword added.
Implement handshake with SOCKS4 proxy server for tcp stream connection.
See issue #82.

I have the "SOCKS: A protocol for TCP proxy across firewalls" doc found
at "https://www.openssh.com/txt/socks4.protocol". Please reference to it.

[wt: for now connecting to the SOCKS4 proxy over unix sockets is not
 supported, and mixing IPv4/IPv6 is discouraged; indeed, the control
 layer is unique for a connection and will be used both for connecting
 and for target address manipulation. As such it may for example report
 incorrect destination addresses in logs if the proxy is reached over
 IPv6]
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index f595029..7ae28f0 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -294,6 +294,7 @@
 	struct proxy *be;
 	struct conn_src *src;
 	int use_fastopen = 0;
+	struct sockaddr_storage *addr;
 
 	conn->flags |= CO_FL_WAIT_L4_CONN; /* connection in progress */
 
@@ -514,7 +515,8 @@
 	if (global.tune.server_rcvbuf)
                 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &global.tune.server_rcvbuf, sizeof(global.tune.server_rcvbuf));
 
-	if (connect(fd, (struct sockaddr *)&conn->addr.to, get_addr_len(&conn->addr.to)) == -1) {
+	addr = (conn->flags & CO_FL_SOCKS4) ? &srv->socks4_addr : &conn->addr.to;
+	if (connect(fd, (const struct sockaddr *)addr, get_addr_len(addr)) == -1) {
 		if (errno == EINPROGRESS || errno == EALREADY) {
 			/* common case, let's wait for connect status */
 			conn->flags |= CO_FL_WAIT_L4_CONN;
@@ -567,10 +569,6 @@
 
 	conn->flags |= CO_FL_ADDR_TO_SET;
 
-	/* Prepare to send a few handshakes related to the on-wire protocol. */
-	if (conn->send_proxy_ofs)
-		conn->flags |= CO_FL_SEND_PROXY;
-
 	conn_ctrl_init(conn);       /* registers the FD */
 	fdtab[fd].linger_risk = 1;  /* close hard if needed */
 
@@ -663,6 +661,7 @@
  */
 int tcp_connect_probe(struct connection *conn)
 {
+	struct sockaddr_storage *addr;
 	int fd = conn->handle.fd;
 	socklen_t lskerr;
 	int skerr;
@@ -701,7 +700,11 @@
 	 *  - connecting (EALREADY, EINPROGRESS)
 	 *  - connected (EISCONN, 0)
 	 */
-	if (connect(fd, (struct sockaddr *)&conn->addr.to, get_addr_len(&conn->addr.to)) < 0) {
+	addr = &conn->addr.to;
+	if ((conn->flags & CO_FL_SOCKS4) && obj_type(conn->target) == OBJ_TYPE_SERVER)
+		addr = &objt_server(conn->target)->socks4_addr;
+
+	if (connect(fd, (const struct sockaddr *)addr, get_addr_len(addr)) == -1) {
 		if (errno == EALREADY || errno == EINPROGRESS) {
 			__conn_sock_stop_recv(conn);
 			fd_cant_send(fd);