summaryrefslogtreecommitdiffstats
path: root/sbin/natd
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2002-01-15 17:07:56 +0000
committerru <ru@FreeBSD.org>2002-01-15 17:07:56 +0000
commit40e62ac22c5a6bdef29ae4594f6d18fdf4c7bc19 (patch)
treea5c043be43c102024390aef269390a4e58b713b1 /sbin/natd
parent60d7a641849b35c71e8194d2da057769a9cd8e30 (diff)
downloadFreeBSD-src-40e62ac22c5a6bdef29ae4594f6d18fdf4c7bc19.zip
FreeBSD-src-40e62ac22c5a6bdef29ae4594f6d18fdf4c7bc19.tar.gz
Back out part of the revision 1.2 changes -- sendto(2) can
not return ENOBUFS for unreliable protocols like divert. This should fix an issue when natd(8) keeps spamming already full dummynet(4) queues with the same packet forever. Spotted by: chkno@dork.com Explained by: luigi Reviewed by: Ari Suutari <ari.suutari@syncrontech.com> MFC after: 2 weeks
Diffstat (limited to 'sbin/natd')
-rw-r--r--sbin/natd/natd.c101
1 files changed, 28 insertions, 73 deletions
diff --git a/sbin/natd/natd.c b/sbin/natd/natd.c
index 9d5fb17..fbb8aed 100644
--- a/sbin/natd/natd.c
+++ b/sbin/natd/natd.c
@@ -97,7 +97,6 @@ static int StrToPortRange (const char* str, const char* proto, port_range *
static int StrToProto (const char* str);
static int StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto, port_range *portRange);
static void ParseArgs (int argc, char** argv);
-static void FlushPacketBuffer (int fd);
static void SetupPunchFW(const char *strValue);
/*
@@ -118,11 +117,6 @@ static int dynamicMode;
static int ifMTU;
static int aliasOverhead;
static int icmpSock;
-static char packetBuf[IP_MAXPACKET];
-static int packetLen;
-static struct sockaddr_in packetAddr;
-static int packetSock;
-static int packetDirection;
static int dropIgnoredIncoming;
static int logDropped;
static int logFacility;
@@ -136,7 +130,6 @@ int main (int argc, char** argv)
int routeSock;
struct sockaddr_in addr;
fd_set readMask;
- fd_set writeMask;
int fdMax;
/*
* Initialize packet aliasing software.
@@ -162,11 +155,6 @@ int main (int argc, char** argv)
logDropped = 0;
logFacility = LOG_DAEMON;
logIpfwDenied = -1;
-/*
- * Mark packet buffer empty.
- */
- packetSock = -1;
- packetDirection = DONT_KNOW;
ParseArgs (argc, argv);
/*
@@ -330,7 +318,7 @@ int main (int argc, char** argv)
while (running) {
- if (divertInOut != -1 && !ifName && packetSock == -1) {
+ if (divertInOut != -1 && !ifName) {
/*
* When using only one socket, just call
* DoAliasing repeatedly to process packets.
@@ -342,30 +330,17 @@ int main (int argc, char** argv)
* Build read mask from socket descriptors to select.
*/
FD_ZERO (&readMask);
- FD_ZERO (&writeMask);
-
-/*
- * If there is unsent packet in buffer, use select
- * to check when socket comes writable again.
- */
- if (packetSock != -1) {
-
- FD_SET (packetSock, &writeMask);
- }
- else {
/*
- * No unsent packet exists - safe to check if
- * new ones are available.
+ * Check if new packets are available.
*/
- if (divertIn != -1)
- FD_SET (divertIn, &readMask);
+ if (divertIn != -1)
+ FD_SET (divertIn, &readMask);
- if (divertOut != -1)
- FD_SET (divertOut, &readMask);
+ if (divertOut != -1)
+ FD_SET (divertOut, &readMask);
- if (divertInOut != -1)
- FD_SET (divertInOut, &readMask);
- }
+ if (divertInOut != -1)
+ FD_SET (divertInOut, &readMask);
/*
* Routing info is processed always.
*/
@@ -374,7 +349,7 @@ int main (int argc, char** argv)
if (select (fdMax + 1,
&readMask,
- &writeMask,
+ NULL,
NULL,
NULL) == -1) {
@@ -384,10 +359,6 @@ int main (int argc, char** argv)
Quit ("Select failed.");
}
- if (packetSock != -1)
- if (FD_ISSET (packetSock, &writeMask))
- FlushPacketBuffer (packetSock);
-
if (divertIn != -1)
if (FD_ISSET (divertIn, &readMask))
DoAliasing (divertIn, INPUT);
@@ -470,9 +441,13 @@ static void DoAliasing (int fd, int direction)
{
int bytes;
int origBytes;
+ char buf[IP_MAXPACKET];
+ struct sockaddr_in addr;
+ int wrote;
int status;
int addrSize;
struct ip* ip;
+ char msgBuf[80];
if (assignAliasAddr) {
@@ -482,12 +457,12 @@ static void DoAliasing (int fd, int direction)
/*
* Get packet from socket.
*/
- addrSize = sizeof packetAddr;
+ addrSize = sizeof addr;
origBytes = recvfrom (fd,
- packetBuf,
- sizeof packetBuf,
+ buf,
+ sizeof buf,
0,
- (struct sockaddr*) &packetAddr,
+ (struct sockaddr*) &addr,
&addrSize);
if (origBytes == -1) {
@@ -500,9 +475,9 @@ static void DoAliasing (int fd, int direction)
/*
* This is a IP packet.
*/
- ip = (struct ip*) packetBuf;
+ ip = (struct ip*) buf;
if (direction == DONT_KNOW) {
- if (packetAddr.sin_addr.s_addr == INADDR_ANY)
+ if (addr.sin_addr.s_addr == INADDR_ANY)
direction = OUTPUT;
else
direction = INPUT;
@@ -541,14 +516,14 @@ static void DoAliasing (int fd, int direction)
/*
* Outgoing packets. Do aliasing.
*/
- PacketAliasOut (packetBuf, IP_MAXPACKET);
+ PacketAliasOut (buf, IP_MAXPACKET);
}
else {
/*
* Do aliasing.
*/
- status = PacketAliasIn (packetBuf, IP_MAXPACKET);
+ status = PacketAliasIn (buf, IP_MAXPACKET);
if (status == PKT_ALIAS_IGNORED &&
dropIgnoredIncoming) {
@@ -583,42 +558,24 @@ static void DoAliasing (int fd, int direction)
printf ("\n");
}
- packetLen = bytes;
- packetSock = fd;
- packetDirection = direction;
-
- FlushPacketBuffer (fd);
-}
-
-static void FlushPacketBuffer (int fd)
-{
- int wrote;
- char msgBuf[80];
/*
* Put packet back for processing.
*/
wrote = sendto (fd,
- packetBuf,
- packetLen,
+ buf,
+ bytes,
0,
- (struct sockaddr*) &packetAddr,
- sizeof packetAddr);
+ (struct sockaddr*) &addr,
+ sizeof addr);
- if (wrote != packetLen) {
-/*
- * If buffer space is not available,
- * just return. Main loop will take care of
- * retrying send when space becomes available.
- */
- if (errno == ENOBUFS)
- return;
+ if (wrote != bytes) {
if (errno == EMSGSIZE) {
- if (packetDirection == OUTPUT &&
+ if (direction == OUTPUT &&
ifMTU != -1)
SendNeedFragIcmp (icmpSock,
- (struct ip*) packetBuf,
+ (struct ip*) buf,
ifMTU - aliasOverhead);
}
else if (errno == EACCES && logIpfwDenied) {
@@ -627,8 +584,6 @@ static void FlushPacketBuffer (int fd)
Warn (msgBuf);
}
}
-
- packetSock = -1;
}
static void HandleRoutingInfo (int fd)
OpenPOWER on IntegriCloud