UDP kernel sockets
UDP kernel sockets
- Subject: UDP kernel sockets
- From: Michael Tüxen <email@hidden>
- Date: Mon, 9 Jun 2008 18:48:43 +0200
Dear all,
I'm using a UDP kernel socket created by (error handling not shown):
error = sock_socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP,
sctp_over_udp_ipv4_cb, NULL, &sctp_over_udp_ipv4_so);
error = sock_setsockopt(sctp_over_udp_ipv4_so, IPPROTO_IP,
IP_RECVDSTADDR, (const void *)&on, (int)sizeof(int));
memset((void *)&addr_ipv4, 0, sizeof(struct sockaddr_in));
addr_ipv4.sin_len = sizeof(struct sockaddr_in);
addr_ipv4.sin_family = AF_INET;
addr_ipv4.sin_port = htons(sctp_udp_tunneling_port);
addr_ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
error = sock_bind(sctp_over_udp_ipv4_so, (const struct sockaddr
*)&addr_ipv4);
and the sctp_over_udp_ipv4_cb looks like (also error handling
suppressed):
void
sctp_over_udp_ipv4_cb(socket_t udp_sock, void *cookie, int watif)
{
errno_t error;
size_t length;
mbuf_t packet;
struct msghdr msg;
struct sockaddr_in src, dst;
char cmsgbuf[CMSG_SPACE(sizeof (struct in_addr))];
struct cmsghdr *cmsg;
struct ip *ip;
struct mbuf *ip_m;
bzero((void *)&msg, sizeof(struct msghdr));
bzero((void *)&src, sizeof(struct sockaddr_in));
bzero((void *)&dst, sizeof(struct sockaddr_in));
bzero((void *)cmsgbuf, CMSG_SPACE(sizeof (struct in_addr)));
msg.msg_name = (void *)&src;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_iov = NULL;
msg.msg_iovlen = 0;
msg.msg_control = (void *)cmsgbuf;
msg.msg_controllen = CMSG_LEN(sizeof (struct in_addr));
msg.msg_flags = 0;
length = (1<<16);
error = sock_receivembuf(udp_sock, &msg, &packet, 0, &length);
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg,
cmsg)) {
if ((cmsg->cmsg_level == IPPROTO_IP) && (cmsg->cmsg_type ==
IP_RECVDSTADDR)) {
dst.sin_family = AF_INET;
dst.sin_len = sizeof(struct sockaddr_in);
dst.sin_port = htons(sctp_udp_tunneling_port);
memcpy((void *)&dst.sin_addr, (const void *)CMSG_DATA(cmsg),
sizeof(struct in_addr));
}
}
ip_m = sctp_get_mbuf_for_msg(sizeof(struct ip), 1, M_DONTWAIT, 1,
MT_DATA);
ip_m->m_pkthdr.rcvif = packet->m_pkthdr.rcvif;
ip = mtod(ip_m, struct ip *);
bzero((void *)ip, sizeof(struct ip));
ip->ip_v = IPVERSION;
ip->ip_len = length;
ip->ip_src = src.sin_addr;
ip->ip_dst = dst.sin_addr;
SCTP_HEADER_LEN(ip_m) = sizeof(struct ip) + length;
SCTP_BUF_LEN(ip_m) = sizeof(struct ip);
SCTP_BUF_NEXT(ip_m) = packet;
sctp_input_with_port(ip_m, sizeof(struct ip), src.sin_port);
return;
}
The code works. However, for each received UDP packet one mbuf for
ancillary data is leaked.
So after a short transfer I see:
[mbp15:~] tuexen% netstat -m
16933/17080 mbufs in use:
473 mbufs allocated to data
16459 mbufs allocated to ancillary data
1 mbufs allocated to Appletalk data blocks
147 mbufs allocated to caches
2854/3664 mbuf 2KB clusters in use
0/16 mbuf 4KB clusters in use
0/0 mbuf 16KB clusters in use
7392 KB allocated to network (69.6% in use)
0 requests for memory denied
0 requests for memory delayed
0 calls to drain routines
Is the code above not correct or is it a bug in the kernel?
Thank you very much for your help!
Best regards
Michael
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden