tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: sendmsg(2) with IP_PKTINFO
>>>
>>> + /* Checking laddr:port already in use? */
>>> + xinp = in_pcblookup_bind(&udbtable,
>>> + laddr.sin_addr, inp->inp_lport);
>>> + if ((xinp != NULL) && (xinp != inp)) {
>>> + error = EADDRINUSE;
>>> + goto release;
>>> + }
>>> + break;
>>>
>>> Why is this check needed and why is it UDP specific?
>>>
>>> In dhcpcd's case it's already bound the local address the socket and the
>>> kernel then claims the address is already in use which is wrong.
>>
>> I thought that it should fail with EADDRINUSE if sendmsg with IP_PKTINFO
>> using address:port same as already bound on other socket.
>>
>> Certainly, this behavior is different from IP6_PKTINFO and linux.
>> Should I fix to be able to PKTINFO with address:port that another socket bound?
>
>Yes please!
>
>Consider this use case:
>https://roy.marples.name/git/dhcpcd.git/tree/src/dhcp.c#n1687
>I am only using IP_PKTINFO to set the outbound interface, not influence
>any address.
>
>As things stand the kernel check noted above returns EADDRINUSE.
>If I either remove the kernel check OR disable IP_PKTINFO in dhcpcd then
>the message is sent.
>
>To make the code easier to read, I bind to the unspecified
>address:BOOTPC so that ICMP unreachable messages are not sent by the
>kernel during DHCP init. This socket is kept open for the lifetime of
>dhcpcd and just drained down.
>
>When dhcpcd needs to unicast to the DHCP server, it opens another
>socket, binds DHCPADDRESS:BOOTPC and then sends. This works fine without
>IP_PKTINFO and I would like to use IP_PKTINFO just to force the outbound
>interface. We're not actively listening on this socket, just sending. My
>expectation is that this should work.
>
>Can you fix this please?
Ok, Please try this patch. If no problem for dhcpcd, I'll commit.
cvs -q diff -aup .
Index: ip_output.c
===================================================================
RCS file: /src/cvs/cvsroot-netbsd/src/sys/netinet/ip_output.c,v
retrieving revision 1.285
diff -a -u -p -r1.285 ip_output.c
--- ip_output.c 17 Nov 2017 07:37:12 -0000 1.285
+++ ip_output.c 8 Dec 2017 16:59:52 -0000
@@ -1411,9 +1411,8 @@ ip_pktinfo_prepare(const struct in_pktin
*/
int
ip_setpktopts(struct mbuf *control, struct ip_pktopts *pktopts, int *flags,
- struct inpcb *inp, kauth_cred_t cred, int uproto)
+ struct inpcb *inp, kauth_cred_t cred)
{
- struct inpcb *xinp;
struct cmsghdr *cm;
struct in_pktinfo *pktinfo;
int error;
@@ -1453,16 +1452,6 @@ ip_setpktopts(struct mbuf *control, stru
cred);
if (error != 0)
return error;
-
- if ((uproto == IPPROTO_UDP) &&
- !in_nullhost(pktopts->ippo_laddr.sin_addr)) {
- /* Checking laddr:port already in use? */
- xinp = in_pcblookup_bind(&udbtable,
- pktopts->ippo_laddr.sin_addr,
- inp->inp_lport);
- if ((xinp != NULL) && (xinp != inp))
- return EADDRINUSE;
- }
break;
default:
return ENOPROTOOPT;
Index: ip_var.h
===================================================================
RCS file: /src/cvs/cvsroot-netbsd/src/sys/netinet/ip_var.h,v
retrieving revision 1.120
diff -a -u -p -r1.120 ip_var.h
--- ip_var.h 10 Aug 2017 04:31:58 -0000 1.120
+++ ip_var.h 8 Dec 2017 17:00:03 -0000
@@ -215,7 +215,7 @@ void in_init(void);
int ip_ctloutput(int, struct socket *, struct sockopt *);
int ip_setpktopts(struct mbuf *, struct ip_pktopts *, int *,
- struct inpcb *, kauth_cred_t, int);
+ struct inpcb *, kauth_cred_t);
void ip_drain(void);
void ip_drainstub(void);
void ip_freemoptions(struct ip_moptions *);
Index: raw_ip.c
===================================================================
RCS file: /src/cvs/cvsroot-netbsd/src/sys/netinet/raw_ip.c,v
retrieving revision 1.166
diff -a -u -p -r1.166 raw_ip.c
--- raw_ip.c 10 Aug 2017 04:31:58 -0000 1.166
+++ raw_ip.c 8 Dec 2017 17:00:08 -0000
@@ -322,8 +322,7 @@ rip_output(struct mbuf *m, struct inpcb
/* Setup IP outgoing packet options */
memset(&pktopts, 0, sizeof(pktopts));
- error = ip_setpktopts(control, &pktopts, &flags, inp, cred,
- IPPROTO_RAW);
+ error = ip_setpktopts(control, &pktopts, &flags, inp, cred);
if (control != NULL)
m_freem(control);
if (error != 0)
Index: udp_usrreq.c
===================================================================
RCS file: /src/cvs/cvsroot-netbsd/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.235
diff -a -u -p -r1.235 udp_usrreq.c
--- udp_usrreq.c 10 Aug 2017 04:31:58 -0000 1.235
+++ udp_usrreq.c 8 Dec 2017 17:00:19 -0000
@@ -804,8 +804,7 @@ udp_output(struct mbuf *m, struct inpcb
/* Setup IP outgoing packet options */
memset(&pktopts, 0, sizeof(pktopts));
- error = ip_setpktopts(control, &pktopts, &flags, inp, cred,
- IPPROTO_UDP);
+ error = ip_setpktopts(control, &pktopts, &flags, inp, cred);
if (error != 0)
goto release;
--
ryo shimizu
Home |
Main Index |
Thread Index |
Old Index