diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk
index 470010e8ba098bef3636a085bc32bc76458bf475..8eeb9497810a1c00497dc20bfb806c653f4e053d 100644
--- a/src/Makefile.d/versions.mk
+++ b/src/Makefile.d/versions.mk
@@ -152,12 +152,8 @@ else
 endif
 
 ifdef DEBUGMODE
-ifdef GCC48
-opts+=-Og
-else
 opts+=-O0
 endif
-endif
 
 ifdef VALGRIND
 ifdef GCC46
diff --git a/src/netcode/d_net.c b/src/netcode/d_net.c
index 5b3503c2c8a224d908779e7dd1500ff3c22bc8df..3b151f20d18bd156b5385b500267244513e32610 100644
--- a/src/netcode/d_net.c
+++ b/src/netcode/d_net.c
@@ -134,8 +134,8 @@ boolean Net_GetNetStat(void)
 // -----------------------------------------------------------------
 // Some structs and functions for acknowledgement of packets
 // -----------------------------------------------------------------
-#define MAXACKPACKETS 96 // Minimum number of nodes (wat)
-#define MAXACKTOSEND 96
+#define MAXACKPACKETS 16 // Minimum number of nodes (wat)
+#define MAXACKTOSEND 16
 #define URGENTFREESLOTNUM 10
 #define ACKTOSENDTIMEOUT (TICRATE/11)
 
@@ -143,7 +143,6 @@ typedef struct
 {
 	UINT8 acknum;
 	UINT8 nextacknum;
-	UINT8 destinationnode; // The node to send the ack to
 	tic_t senttime; // The time when the ack was sent
 	UINT16 length; // The packet size
 	UINT16 resentnum; // The number of times the ack has been resent
@@ -160,10 +159,11 @@ typedef enum
 } node_flags_t;
 
 // Table of packets that were not acknowleged can be resent (the sender window)
-static ackpak_t ackpak[MAXACKPACKETS];
 
 typedef struct
 {
+	// acks that has been sent but not yet acknowledged
+	ackpak_t ackpak[MAXACKPACKETS];
 	// ack return to send (like sliding window protocol)
 	UINT8 firstacktosend;
 
@@ -200,6 +200,7 @@ static boolean GetFreeAcknum(UINT8 *freeack)
 {
 	node_t *node = &nodes[doomcom->remotenode];
 	INT32 numfreeslot = 0;
+	INT32 i;
 
 	if (cmpack((UINT8)((node->remotefirstack + MAXACKTOSEND) % 256), node->nextacknum) < 0)
 	{
@@ -207,8 +208,8 @@ static boolean GetFreeAcknum(UINT8 *freeack)
 		return false;
 	}
 
-	for (INT32 i = 0; i < MAXACKPACKETS; i++)
-		if (!ackpak[i].acknum)
+	for (i = 0; i < MAXACKPACKETS; i++)
+		if (!node->ackpak[i].acknum)
 		{
 			// For low priority packets, make sure to let freeslots so urgent packets can be sent
 			if (netbuffer->packettype >= PT_CANFAIL)
@@ -218,28 +219,31 @@ static boolean GetFreeAcknum(UINT8 *freeack)
 					continue;
 			}
 
-			ackpak[i].acknum = node->nextacknum;
-			ackpak[i].nextacknum = node->nextacknum;
+			node->ackpak[i].acknum = node->nextacknum;
+			node->ackpak[i].nextacknum = node->nextacknum;
 			node->nextacknum++;
 			if (!node->nextacknum)
 				node->nextacknum++;
-			ackpak[i].destinationnode = (UINT8)(node - nodes);
-			ackpak[i].length = doomcom->datalength;
-			ackpak[i].senttime = I_GetTime();
-			ackpak[i].resentnum = 0;
-			M_Memcpy(ackpak[i].pak.raw, netbuffer, ackpak[i].length);
+			node->ackpak[i].length = doomcom->datalength;
+			node->ackpak[i].senttime = I_GetTime();
+			node->ackpak[i].resentnum = 0;
+			M_Memcpy(node->ackpak[i].pak.raw, netbuffer, node->ackpak[i].length);
 
-			*freeack = ackpak[i].acknum;
+			*freeack = node->ackpak[i].acknum;
 
 			sendackpacket++; // For stat
 
 			return true;
 		}
+
 #ifdef PARANOIA
 	CONS_Debug(DBG_NETPLAY, "No more free ackpacket\n");
 #endif
 	if (netbuffer->packettype < PT_CANFAIL)
-		I_Error("Connection lost\n");
+	{
+		CONS_Alert(CONS_WARNING, "Connection from %s is not acknowledging packets, killing connection\n", I_GetNodeAddress(doomcom->remotenode));
+		Net_CloseConnection(doomcom->remotenode | FORCECLOSE);
+	}
 	return false;
 }
 
@@ -250,13 +254,12 @@ static UINT8 GetAcktosend(INT32 node)
 	return nodes[node].firstacktosend;
 }
 
-static void RemoveAck(INT32 i)
+static void RemoveAck(node_t *node, INT32 i)
 {
-	INT32 node = ackpak[i].destinationnode;
-	DEBFILE(va("Remove ack %d\n",ackpak[i].acknum));
-	ackpak[i].acknum = 0;
-	if (nodes[node].flags & NF_CLOSE)
-		Net_CloseConnection(node);
+	DEBFILE(va("Remove ack %d\n",node->ackpak[i].acknum));
+	node->ackpak[i].acknum = 0;
+	if (node->flags & NF_CLOSE)
+		Net_CloseConnection(node-nodes);
 }
 
 // We have got a packet, proceed the ack request and ack return
@@ -271,10 +274,9 @@ static boolean Processackpak(void)
 		node->remotefirstack = netbuffer->ackreturn;
 		// Search the ackbuffer and free it
 		for (INT32 i = 0; i < MAXACKPACKETS; i++)
-			if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode
-				&& cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0)
+			if (node->ackpak[i].acknum && cmpack(node->ackpak[i].acknum, netbuffer->ackreturn) <= 0)
 			{
-				RemoveAck(i);
+				RemoveAck(node, i);
 			}
 	}
 
@@ -338,31 +340,32 @@ void Net_ConnectionTimeout(INT32 node)
 // Resend the data if needed
 void Net_AckTicker(void)
 {
-
-	for (INT32 i = 0; i < MAXACKPACKETS; i++)
+	for (INT32 nodei = 0; nodei < numnetnodes; nodei++)
 	{
-		const INT32 nodei = ackpak[i].destinationnode;
-		node_t *node = &nodes[nodei];
-		if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime())
+		for (INT32 i = 0; i < MAXACKPACKETS; i++)
 		{
-			if (ackpak[i].resentnum > 20 && (node->flags & NF_CLOSE))
+			node_t *node = &nodes[nodei];
+			if (node->ackpak[i].acknum && node->ackpak[i].senttime + NODETIMEOUT < I_GetTime())
 			{
-				DEBFILE(va("ack %d sent 20 times so connection is supposed lost: node %d\n",
-					i, nodei));
-				Net_CloseConnection(nodei | FORCECLOSE);
+				if (node->ackpak[i].resentnum > 20 && (node->flags & NF_CLOSE))
+				{
+					DEBFILE(va("ack %d sent 20 times so connection is supposed lost: node %d\n",
+						i, nodei));
+					Net_CloseConnection(nodei | FORCECLOSE);
 
-				ackpak[i].acknum = 0;
-				continue;
+					node->ackpak[i].acknum = 0;
+					continue;
+				}
+				DEBFILE(va("Resend ack %d, %u<%d at %u\n", node->ackpak[i].acknum, node->ackpak[i].senttime,
+					NODETIMEOUT, I_GetTime()));
+				M_Memcpy(netbuffer, node->ackpak[i].pak.raw, node->ackpak[i].length);
+				node->ackpak[i].senttime = I_GetTime();
+				node->ackpak[i].resentnum++;
+				node->ackpak[i].nextacknum = node->nextacknum;
+				retransmit++; // For stat
+				HSendPacket((INT32)(node - nodes), false, node->ackpak[i].acknum,
+					(size_t)(node->ackpak[i].length - BASEPACKETSIZE));
 			}
-			DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime,
-				NODETIMEOUT, I_GetTime()));
-			M_Memcpy(netbuffer, ackpak[i].pak.raw, ackpak[i].length);
-			ackpak[i].senttime = I_GetTime();
-			ackpak[i].resentnum++;
-			ackpak[i].nextacknum = node->nextacknum;
-			retransmit++; // For stat
-			HSendPacket((INT32)(node - nodes), false, ackpak[i].acknum,
-				(size_t)(ackpak[i].length - BASEPACKETSIZE));
 		}
 	}
 
@@ -399,9 +402,12 @@ void Net_UnAcknowledgePacket(INT32 node)
   */
 static boolean Net_AllAcksReceived(void)
 {
-	for (INT32 i = 0; i < MAXACKPACKETS; i++)
-		if (ackpak[i].acknum)
-			return false;
+	for (INT32 nodei = 0; nodei < numnetnodes; nodei++)
+	{
+		for (INT32 i = 0; i < MAXACKPACKETS; i++)
+			if (nodes[nodei].ackpak[i].acknum)
+				return false;
+	}
 
 	return true;
 }
@@ -436,32 +442,17 @@ static void InitNode(node_t *node)
 	node->nextacknum = 1;
 	node->remotefirstack = 0;
 	node->flags = 0;
+
+	for (INT32 i = 0; i < MAXACKPACKETS; i++)
+		node->ackpak[i].acknum = 0;
 }
 
 static void InitAck(void)
 {
-	for (INT32 i = 0; i < MAXACKPACKETS; i++)
-		ackpak[i].acknum = 0;
-
 	for (INT32 i = 0; i < MAXNETNODES; i++)
 		InitNode(&nodes[i]);
 }
 
-/** Removes all acks of a given packet type
-  *
-  * \param packettype The packet type to forget
-  *
-  */
-void Net_AbortPacketType(UINT8 packettype)
-{
-	for (INT32 i = 0; i < MAXACKPACKETS; i++)
-		if (ackpak[i].acknum && (ackpak[i].pak.data.packettype == packettype
-			|| packettype == UINT8_MAX))
-		{
-			ackpak[i].acknum = 0;
-		}
-}
-
 // -----------------------------------------------------------------
 // end of acknowledge function
 // -----------------------------------------------------------------
@@ -496,15 +487,21 @@ void Net_CloseConnection(INT32 node)
 		netbuffer->packettype = PT_NOTHING;
 		HSendPacket(node, false, 0, 0);
 	}
+	else
+	{
+		// if the connection hasn't acknowledged anything, it's possible for it to permanently occupy the node.
+		// to prevent this, drop the connection.
+		forceclose = true;
+	}
 
 	// check if we are waiting for an ack from this node
 	for (INT32 i = 0; i < MAXACKPACKETS; i++)
-		if (ackpak[i].acknum && ackpak[i].destinationnode == node)
+		if (nodes[node].ackpak[i].acknum)
 		{
 			if (!forceclose)
 				return; // connection will be closed when ack is returned
 			else
-				ackpak[i].acknum = 0;
+				nodes[node].ackpak[i].acknum = 0;
 		}
 
 	InitNode(&nodes[node]);
diff --git a/src/netcode/d_net.h b/src/netcode/d_net.h
index 6b3ee5e6751bd6d19457ea704274b5de9247c483..c07f9baf9bcd899988db7afda21432dbf26b73ac 100644
--- a/src/netcode/d_net.h
+++ b/src/netcode/d_net.h
@@ -73,7 +73,6 @@ boolean Net_IsNodeIPv6(INT32 node);
 void Net_UnAcknowledgePacket(INT32 node);
 void Net_CloseConnection(INT32 node);
 void Net_ConnectionTimeout(INT32 node);
-void Net_AbortPacketType(UINT8 packettype);
 void Net_SendAcks(INT32 node);
 void Net_WaitAllAckReceived(UINT32 timeout);