Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Oct 2007 17:40:57 +0200
From:      Matus Harvan <mharvan@inf.ethz.ch>
To:        freebsd-net@freebsd.org
Cc:        Max Laier <max@love2party.net>, Brooks Davis <brooks@freebsd.org>
Subject:   Re: UDP catchall
Message-ID:  <20071026154057.GG1049@styx.ethz.ch>
In-Reply-To: <20070909201837.GA18107@inf.ethz.ch>
References:  <20070909201837.GA18107@inf.ethz.ch>

next in thread | previous in thread | raw e-mail | index | archive | help

--OFj+1YLvsEfSXdCH
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hi,

I was wondering if I could get some feedback about the patch and
whether others think it could be committed.

Matus

On Sun, Sep 09, 2007 at 10:18:37PM +0200, Matus Harvan wrote:
> Hello,
>=20
> I am a Google Summer of Code student working on mtund, aka Magic
> Tunnel Daemon aka Super Tunnel Daemon,
> http://wiki.freebsd.org/SuperTunnelDaemon.
>=20
> For mtund it would be useful to listen on all unused UDP ports,
> allowing a client behind firewall to use any possible hole it could
> find. To achieve this, the easiest way seems to be to allow a raw
> IP/UDP socket to receive UDP traffic that no regular UDP socket
> wants. In the kernel this means passing the mbuf from udp_input to
> rip_input(). Upon receiving a packet, the user space program would
> inspect the UDP header and create a UDP socket bound to the correct
> local port and connected to the right remote port and address.
>=20
> The user space usage would then look as follows:
> 	fd =3D socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
> 	recvfrom(fd, ...);
> 	/* parse the UDP header for the source and destination addresses */
> 	new_fd =3D socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
> 	bind(new_fd, ...);
> 	connect(new_fd, ...);
>=20
> This catchall feature could be enabled/disabled via a sysctl variable,
> net.inet.raw.udp_catchall. Furthermore, a rate limit could be used to
> mitigate possible DoS misuse.
>=20
> A simple testing program can be found under
>=20
> http://p4web.freebsd.org/@md=3Dd&cd=3D//depot/projects/soc2007/mharvan-mt=
und/sys.patches/test_catchall/&c=3Dxpc@//depot/projects/soc2007/mharvan-mtu=
nd/sys.patches/test_catchall/ucatchalld.c?ac=3D22
>=20
> and a more complex example is the udp catchall plugin for mtund
>=20
> http://p4web.freebsd.org/@md=3Dd&cd=3D//depot/projects/soc2007/mharvan-mt=
und/mtund.src/&c=3DSM3@//depot/projects/soc2007/mharvan-mtund/mtund.src/plu=
gin_udp_catchall.c?ac=3D22
>=20
> Matus
>=20
> patch:
> Index: udp_usrreq.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v
> retrieving revision 1.216
> diff -d -u -r1.216 udp_usrreq.c
> --- udp_usrreq.c	10 Jul 2007 09:30:46 -0000	1.216
> +++ udp_usrreq.c	6 Sep 2007 21:59:31 -0000
> @@ -125,6 +125,15 @@
>  SYSCTL_ULONG(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
>      &udp_recvspace, 0, "Maximum space for incoming UDP datagrams");
> =20
> +static int	udp_catchall =3D 0;
> +SYSCTL_INT(_net_inet_raw, OID_AUTO, udp_catchall, CTLFLAG_RW | CTLFLAG_S=
ECURE,
> +   &udp_catchall, 0, "Raw IP UDP sockets receive unclaimed UDP datagrams=
");
> +
> +static int	catchalllim =3D 5;
> +SYSCTL_INT(_net_inet_udp, OID_AUTO, catchalllim, CTLFLAG_RW | CTLFLAG_SE=
CURE,
> +   &catchalllim, 0,
> +   "Rate limit on received UDP datagrams due to udp_catchall");
> +
>  struct inpcbhead	udb;		/* from udp_var.h */
>  struct inpcbinfo	udbinfo;
> =20
> @@ -136,6 +145,11 @@
>  SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RW, &udpstat,
>      udpstat, "UDP statistics (struct udpstat, netinet/udp_var.h)");
> =20
> +static struct rate {
> +  struct timeval	lasttime;
> +  int		curpps;
> +} catchallr;
> +
>  static void	udp_detach(struct socket *so);
>  static int	udp_output(struct inpcb *, struct mbuf *, struct sockaddr *,
>  		    struct mbuf *, struct thread *);
> @@ -515,6 +529,35 @@
>  	 */
>  	inp =3D in_pcblookup_hash(&udbinfo, ip->ip_src, uh->uh_sport,
>  	    ip->ip_dst, uh->uh_dport, 1, ifp);
> +
> +	/* catchall socket */
> +	if (inp =3D=3D NULL && udp_catchall !=3D 0) {
> +#ifdef DIAGNOSTIC
> +		printf("IP UDP catchall active\n");
> +		char dbuf[INET_ADDRSTRLEN], sbuf[INET_ADDRSTRLEN];
> +		strcpy(dbuf, inet_ntoa(ip->ip_dst));
> +		strcpy(sbuf, inet_ntoa(ip->ip_src));
> +		printf("\tip_src: %s, sport: %hu\n\tip_dst: %s, dport: %hu\n",
> +		    sbuf, ntohs(uh->uh_sport), dbuf, ntohs(uh->uh_dport));
> +#endif
> +
> +		/* rate limiting */
> +		if (catchalllim > 0)=20
> +			if (ppsratecheck(&catchallr.lasttime,
> +			    &catchallr.curpps, catchalllim)) {
> +				rip_input(m, off);
> +				INP_INFO_RUNLOCK(&udbinfo);
> +				return;
> +			}
> +#ifdef DIAGNOSTIC
> +			else
> +			  printf("ppsratecheck limited "
> +				    "udp_catchall\n");
> +		else
> +			printf("ppsratecheck limited udp_catchall\n");
> +#endif
> +	}
> +
>  	if (inp =3D=3D NULL) {
>  		if (udp_log_in_vain) {
>  			char buf[4*sizeof "123"];



--OFj+1YLvsEfSXdCH
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4 (FreeBSD)

iD8DBQFHIgqJ43LQWDWf0QIRAgIAAJ4qBMV3eVP883IKwzb6faqkphuIYwCfa+wU
fJpmJ24+fQqkUiTCl7Hwe5g=
=vev9
-----END PGP SIGNATURE-----

--OFj+1YLvsEfSXdCH--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20071026154057.GG1049>