On Mon, Apr 11, 2011 at 16:59 +0200, Mike Belopuhov wrote:
> On Thu, Apr 07, 2011 at 18:58 +0200, Mike Belopuhov wrote:
> > this allows us to get rid of the nasty NATLOOKUP ioctl and get
> > the original server address right from the socket.  also this
> > paves the way to the transparent ftp-proxy mode.
> > 
> > if you will like this diff and nobody objects, i'll try to rip
> > NATLOOKUP out from the other places too.
> > 
> > note, that it requires you to change your rdr-to rule to do
> > divert:
> > 
> >  -pass in quick proto tcp to port ftp rdr-to 127.0.0.1 port 8021
> >  +pass in quick proto tcp to port ftp divert-to 127.0.0.1 port 8021
> > 
> > 
> 
> new version.  correct operation with rdomains requires the divert-to
> rdomain diff.
> 

as the divert-to rdomain diff is in, i'm looking for OKs for this one.

> Index: filter.c
> ===================================================================
> RCS file: /home/cvs/src/usr.sbin/ftp-proxy/filter.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 filter.c
> --- filter.c  25 Mar 2011 14:51:31 -0000      1.14
> +++ filter.c  7 Apr 2011 16:52:05 -0000
> @@ -42,10 +42,6 @@
>  int add_addr(struct sockaddr *, struct pf_pool *);
>  int prepare_rule(u_int32_t, struct sockaddr *, struct sockaddr *,
>      u_int16_t);
> -int server_lookup4(struct sockaddr_in *, struct sockaddr_in *,
> -    struct sockaddr_in *, int *);
> -int server_lookup6(struct sockaddr_in6 *, struct sockaddr_in6 *,
> -    struct sockaddr_in6 *, int *);
>  
>  static struct pfioc_rule     pfr;
>  static struct pfioc_trans    pft;
> @@ -252,82 +248,6 @@ prepare_rule(u_int32_t id, struct sockad
>               strlcpy(pfr.rule.tagname, tagname,
>                                 sizeof pfr.rule.tagname);
>       }
> -
> -     return (0);
> -}
> -
> -int
> -server_lookup(struct sockaddr *client, struct sockaddr *proxy,
> -    struct sockaddr *server, int *cdomain)
> -{
> -     if (client->sa_family == AF_INET)
> -             return (server_lookup4(satosin(client), satosin(proxy),
> -                 satosin(server), cdomain));
> -     
> -     if (client->sa_family == AF_INET6)
> -             return (server_lookup6(satosin6(client), satosin6(proxy),
> -                 satosin6(server), cdomain));
> -
> -     errno = EPROTONOSUPPORT;
> -     return (-1);
> -}
> -
> -int
> -server_lookup4(struct sockaddr_in *client, struct sockaddr_in *proxy,
> -    struct sockaddr_in *server, int *cdomain)
> -{
> -     struct pfioc_natlook pnl;
> -
> -     memset(&pnl, 0, sizeof pnl);
> -     pnl.direction = PF_OUT;
> -     pnl.af = AF_INET;
> -     pnl.proto = IPPROTO_TCP;
> -     pnl.rdomain = getrtable();
> -     memcpy(&pnl.saddr.v4, &client->sin_addr.s_addr, sizeof pnl.saddr.v4);
> -     memcpy(&pnl.daddr.v4, &proxy->sin_addr.s_addr, sizeof pnl.daddr.v4);
> -     pnl.sport = client->sin_port;
> -     pnl.dport = proxy->sin_port;
> -     
> -     if (ioctl(dev, DIOCNATLOOK, &pnl) == -1)
> -             return (-1);
> -
> -     memset(server, 0, sizeof(struct sockaddr_in));
> -     server->sin_len = sizeof(struct sockaddr_in);
> -     server->sin_family = AF_INET;
> -     memcpy(&server->sin_addr.s_addr, &pnl.rdaddr.v4,
> -         sizeof server->sin_addr.s_addr);
> -     server->sin_port = pnl.rdport;
> -     *cdomain = pnl.rrdomain;
> -
> -     return (0);
> -}
> -
> -int
> -server_lookup6(struct sockaddr_in6 *client, struct sockaddr_in6 *proxy,
> -    struct sockaddr_in6 *server, int *cdomain)
> -{
> -     struct pfioc_natlook pnl;
> -
> -     memset(&pnl, 0, sizeof pnl);
> -     pnl.direction = PF_OUT;
> -     pnl.af = AF_INET6;
> -     pnl.proto = IPPROTO_TCP;
> -     pnl.rdomain = getrtable();
> -     memcpy(&pnl.saddr.v6, &client->sin6_addr.s6_addr, sizeof pnl.saddr.v6);
> -     memcpy(&pnl.daddr.v6, &proxy->sin6_addr.s6_addr, sizeof pnl.daddr.v6);
> -     pnl.sport = client->sin6_port;
> -     pnl.dport = proxy->sin6_port;
> -     
> -     if (ioctl(dev, DIOCNATLOOK, &pnl) == -1)
> -             return (-1);
> -
> -     memset(server, 0, sizeof(struct sockaddr_in6));
> -     server->sin6_len = sizeof(struct sockaddr_in6);
> -     server->sin6_family = AF_INET6;
> -     memcpy(&server->sin6_addr.s6_addr, &pnl.rdaddr.v6,
> -         sizeof server->sin6_addr);
> -     server->sin6_port = pnl.rdport;
> -     *cdomain = pnl.rrdomain;
>  
>       return (0);
>  }
> Index: filter.h
> ===================================================================
> RCS file: /home/cvs/src/usr.sbin/ftp-proxy/filter.h,v
> retrieving revision 1.6
> diff -u -p -r1.6 filter.h
> --- filter.h  25 Mar 2011 14:51:31 -0000      1.6
> +++ filter.h  7 Apr 2011 16:31:38 -0000
> @@ -26,5 +26,3 @@ int do_commit(void);
>  int do_rollback(void);
>  void init_filter(char *, char *, int);
>  int prepare_commit(u_int32_t);
> -int server_lookup(struct sockaddr *, struct sockaddr *, struct sockaddr *,
> -    int *);
> Index: ftp-proxy.8
> ===================================================================
> RCS file: /home/cvs/src/usr.sbin/ftp-proxy/ftp-proxy.8,v
> retrieving revision 1.14
> diff -u -p -r1.14 ftp-proxy.8
> --- ftp-proxy.8       21 Nov 2009 13:59:31 -0000      1.14
> +++ ftp-proxy.8       7 Apr 2011 16:49:56 -0000
> @@ -40,7 +40,7 @@
>  is a proxy for the Internet File Transfer Protocol.
>  FTP control connections should be redirected into the proxy using the
>  .Xr pf 4
> -.Ar rdr-to
> +.Ar divert-to
>  command, after which the proxy connects to the server on behalf of
>  the client.
>  .Pp
> @@ -169,7 +169,7 @@ needs the following rules.
>  Adjust the rules as needed.
>  .Bd -literal -offset 2n
>  anchor "ftp-proxy/*"
> -pass in quick proto tcp to port ftp rdr-to 127.0.0.1 port 8021
> +pass in quick proto tcp to port ftp divert-to 127.0.0.1 port 8021
>  .Ed
>  .Sh SEE ALSO
>  .Xr ftp 1 ,
> Index: ftp-proxy.c
> ===================================================================
> RCS file: /home/cvs/src/usr.sbin/ftp-proxy/ftp-proxy.c,v
> retrieving revision 1.21
> diff -u -p -r1.21 ftp-proxy.c
> --- ftp-proxy.c       25 Mar 2011 14:51:31 -0000      1.21
> +++ ftp-proxy.c       8 Apr 2011 10:29:57 -0000
> @@ -423,14 +423,23 @@ handle_connection(const int listen_fd, s
>        * Find out the real server and port that the client wanted.
>        */
>       len = sizeof(struct sockaddr_storage);
> -     if ((getsockname(s->client_fd, client_to_proxy_sa, &len)) < 0) {
> +     if (getsockname(s->client_fd, server_sa, &len) < 0) {
>               logmsg(LOG_CRIT, "#%d getsockname failed: %s", s->id,
>                   strerror(errno));
>               goto fail;
>       }
> -     if (server_lookup(client_sa, client_to_proxy_sa, server_sa,
> -         &s->client_rd) != 0) {
> -             logmsg(LOG_CRIT, "#%d server lookup failed (no rdr?)", s->id);
> +     len = sizeof(struct sockaddr_storage);
> +     if (getpeername(s->client_fd, client_to_proxy_sa, &len) < 0) {
> +             logmsg(LOG_CRIT, "#%d getpeername failed: %s", s->id,
> +                 strerror(errno));
> +             goto fail;
> +     }
> +     len = sizeof(s->client_rd);
> +     if (client_to_proxy_sa->sa_family == AF_INET &&
> +         getsockopt(s->client_fd, IPPROTO_IP, SO_RTABLE, &s->client_rd,
> +         &len)) {
> +             logmsg(LOG_CRIT, "#%d getsockopt failed: %s", s->id,
> +                 strerror(errno));
>               goto fail;
>       }
>       if (fixed_server) {

Reply via email to