version 1.195, 2014/05/18 14:46:16 |
version 1.196, 2014/05/19 02:51:25 |
Line 175 static void udp_notify (struct inpcb *, |
|
Line 175 static void udp_notify (struct inpcb *, |
|
#endif |
#endif |
int udbhashsize = UDBHASHSIZE; |
int udbhashsize = UDBHASHSIZE; |
|
|
|
/* |
|
* For send - really max datagram size; for receive - 40 1K datagrams. |
|
*/ |
|
static int udp_sendspace = 9216; |
|
static int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in)); |
|
|
#ifdef MBUFTRACE |
#ifdef MBUFTRACE |
struct mowner udp_mowner = MOWNER_INIT("udp", ""); |
struct mowner udp_mowner = MOWNER_INIT("udp", ""); |
struct mowner udp_rx_mowner = MOWNER_INIT("udp", "rx"); |
struct mowner udp_rx_mowner = MOWNER_INIT("udp", "rx"); |
|
|
return (error); |
return (error); |
} |
} |
|
|
int udp_sendspace = 9216; /* really max datagram size */ |
static int |
int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in)); |
udp_attach(struct socket *so, int proto) |
/* 40 1K datagrams */ |
{ |
|
struct inpcb *inp; |
|
int error; |
|
|
|
KASSERT(sotoinpcb(so) == NULL); |
|
|
|
/* Assign the lock (must happen even if we will error out). */ |
|
sosetlock(so); |
|
|
|
#ifdef MBUFTRACE |
|
so->so_mowner = &udp_mowner; |
|
so->so_rcv.sb_mowner = &udp_rx_mowner; |
|
so->so_snd.sb_mowner = &udp_tx_mowner; |
|
#endif |
|
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { |
|
error = soreserve(so, udp_sendspace, udp_recvspace); |
|
if (error) { |
|
return error; |
|
} |
|
} |
|
|
|
error = in_pcballoc(so, &udbtable); |
|
if (error) { |
|
return error; |
|
} |
|
inp = sotoinpcb(so); |
|
inp->inp_ip.ip_ttl = ip_defttl; |
|
KASSERT(solocked(so)); |
|
|
|
return error; |
|
} |
|
|
|
static void |
|
udp_detach(struct socket *so) |
|
{ |
|
struct inpcb *inp; |
|
|
|
KASSERT(solocked(so)); |
|
inp = sotoinpcb(so); |
|
KASSERT(inp != NULL); |
|
in_pcbdetach(inp); |
|
} |
|
|
static int |
static int |
udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, |
udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, |
struct mbuf *control, struct lwp *l) |
struct mbuf *control, struct lwp *l) |
{ |
{ |
struct inpcb *inp; |
struct inpcb *inp; |
int s; |
int s, error = 0; |
int error = 0; |
|
|
|
if (req == PRU_CONTROL) |
KASSERT(req != PRU_ATTACH); |
return (in_control(so, (long)m, (void *)nam, |
KASSERT(req != PRU_DETACH); |
(struct ifnet *)control, l)); |
|
|
|
|
if (req == PRU_CONTROL) { |
|
return in_control(so, (long)m, (void *)nam, |
|
(struct ifnet *)control, l); |
|
} |
s = splsoftnet(); |
s = splsoftnet(); |
|
|
if (req == PRU_PURGEIF) { |
if (req == PRU_PURGEIF) { |
mutex_enter(softnet_lock); |
mutex_enter(softnet_lock); |
in_pcbpurgeif0(&udbtable, (struct ifnet *)control); |
in_pcbpurgeif0(&udbtable, (struct ifnet *)control); |
Line 1216 udp_usrreq(struct socket *so, int req, s |
|
Line 1264 udp_usrreq(struct socket *so, int req, s |
|
in_pcbpurgeif(&udbtable, (struct ifnet *)control); |
in_pcbpurgeif(&udbtable, (struct ifnet *)control); |
mutex_exit(softnet_lock); |
mutex_exit(softnet_lock); |
splx(s); |
splx(s); |
return (0); |
return 0; |
} |
} |
|
|
|
KASSERT(solocked(so)); |
inp = sotoinpcb(so); |
inp = sotoinpcb(so); |
#ifdef DIAGNOSTIC |
|
if (req != PRU_SEND && req != PRU_SENDOOB && control) |
KASSERT(!control || (req == PRU_SEND || req == PRU_SENDOOB)); |
panic("udp_usrreq: unexpected control mbuf"); |
if (inp == NULL) { |
#endif |
splx(s); |
if (req == PRU_ATTACH) { |
return EINVAL; |
sosetlock(so); |
|
} else if (inp == 0) { |
|
error = EINVAL; |
|
goto release; |
|
} |
} |
|
|
/* |
/* |
Line 1236 udp_usrreq(struct socket *so, int req, s |
|
Line 1281 udp_usrreq(struct socket *so, int req, s |
|
* the udp pcb queue and/or pcb addresses. |
* the udp pcb queue and/or pcb addresses. |
*/ |
*/ |
switch (req) { |
switch (req) { |
|
|
case PRU_ATTACH: |
|
if (inp != 0) { |
|
error = EISCONN; |
|
break; |
|
} |
|
#ifdef MBUFTRACE |
|
so->so_mowner = &udp_mowner; |
|
so->so_rcv.sb_mowner = &udp_rx_mowner; |
|
so->so_snd.sb_mowner = &udp_tx_mowner; |
|
#endif |
|
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { |
|
error = soreserve(so, udp_sendspace, udp_recvspace); |
|
if (error) |
|
break; |
|
} |
|
error = in_pcballoc(so, &udbtable); |
|
if (error) |
|
break; |
|
inp = sotoinpcb(so); |
|
inp->inp_ip.ip_ttl = ip_defttl; |
|
break; |
|
|
|
case PRU_DETACH: |
|
in_pcbdetach(inp); |
|
break; |
|
|
|
case PRU_BIND: |
case PRU_BIND: |
error = in_pcbbind(inp, nam, l); |
error = in_pcbbind(inp, nam, l); |
break; |
break; |
Line 1365 udp_usrreq(struct socket *so, int req, s |
|
Line 1383 udp_usrreq(struct socket *so, int req, s |
|
default: |
default: |
panic("udp_usrreq"); |
panic("udp_usrreq"); |
} |
} |
|
|
release: |
|
splx(s); |
splx(s); |
return (error); |
|
|
return error; |
} |
} |
|
|
static int |
static int |
Line 1591 PR_WRAP_USRREQ(udp_usrreq) |
|
Line 1608 PR_WRAP_USRREQ(udp_usrreq) |
|
#define udp_usrreq udp_usrreq_wrapper |
#define udp_usrreq udp_usrreq_wrapper |
|
|
const struct pr_usrreqs udp_usrreqs = { |
const struct pr_usrreqs udp_usrreqs = { |
|
.pr_attach = udp_attach, |
|
.pr_detach = udp_detach, |
.pr_generic = udp_usrreq, |
.pr_generic = udp_usrreq, |
}; |
}; |