diff --git a/src/simutrans/network/network_address.cc b/src/simutrans/network/network_address.cc
index 552be2d40..dc1abd922 100644
--- a/src/simutrans/network/network_address.cc
+++ b/src/simutrans/network/network_address.cc
@@ -57,6 +57,12 @@ void address_list_t::rdwr(packet_t *packet)
 {
 	uint32 count = get_count();
 	packet->rdwr_long(count);
+	// Each entry costs 8 bytes on the wire (ip + mask); refuse a count
+	// beyond what the packet body can hold.
+	if (packet->is_loading()  &&  count > (MAX_PACKET_LEN - HEADER_SIZE) / 8) {
+		packet->failed();
+		return;
+	}
 	for(uint32 i=0; i<count; i++) {
 		if (packet->is_loading()) {
 			append(net_address_t());
diff --git a/src/simutrans/network/network_cmd.cc b/src/simutrans/network/network_cmd.cc
index a188aa20b..03d53e82f 100644
--- a/src/simutrans/network/network_cmd.cc
+++ b/src/simutrans/network/network_cmd.cc
@@ -109,7 +109,14 @@ void nwc_auth_player_t::rdwr()
 
 nwc_service_t::~nwc_service_t()
 {
-	delete socket_info;
+	// vector_tpl<T*> only frees its own array, not the pointed-to
+	// elements.
+	if (socket_info) {
+		for (socket_info_t *si : *socket_info) {
+			delete si;
+		}
+		delete socket_info;
+	}
 	delete address_list;
 	free(text);
 }
diff --git a/src/simutrans/network/network_socket_list.cc b/src/simutrans/network/network_socket_list.cc
index e391e1a1e..fb5a57de2 100644
--- a/src/simutrans/network/network_socket_list.cc
+++ b/src/simutrans/network/network_socket_list.cc
@@ -19,6 +19,12 @@ bool connection_info_t::operator==(const connection_info_t& other) const
 }
 
 
+socket_info_t::~socket_info_t()
+{
+	reset();
+}
+
+
 void socket_info_t::reset()
 {
 	delete packet;
@@ -415,6 +421,12 @@ void socket_list_t::rdwr(packet_t *p, vector_tpl<socket_info_t*> *list)
 	assert(p->is_saving()  ||  list!=&socket_list_t::list);
 	uint32 count = list->get_count();
 	p->rdwr_long(count);
+	// Each entry costs at least one byte on the wire (the state byte
+	// below); refuse a count beyond what the packet body can hold.
+	if (p->is_loading()  &&  count > MAX_PACKET_LEN - HEADER_SIZE) {
+		p->failed();
+		return;
+	}
 	for(uint32 i=0; i<count; i++) {
 		if (p->is_loading()) {
 			list->append(new socket_info_t());
