=== modified file 'uspace/srv/net/inetsrv/pdu.c'
--- uspace/srv/net/inetsrv/pdu.c	2013-09-29 22:05:07 +0000
+++ uspace/srv/net/inetsrv/pdu.c	2013-10-31 17:51:03 +0000
@@ -105,10 +105,10 @@
     size_t offs, size_t mtu, void **rdata, size_t *rsize, size_t *roffs)
 {
 	/* Upper bound for fragment offset field */
-	size_t fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
+	size_t fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l+1);
 	
 	/* Verify that total size of datagram is within reasonable bounds */
-	if (offs + packet->size > FRAG_OFFS_UNIT * fragoff_limit)
+	if ( packet->size > FRAG_OFFS_UNIT * fragoff_limit)
 		return ELIMIT;
 	
 	size_t hdr_size = sizeof(ip_header_t);

=== modified file 'uspace/srv/net/inetsrv/reass.c'
--- uspace/srv/net/inetsrv/reass.c	2013-09-10 16:32:35 +0000
+++ uspace/srv/net/inetsrv/reass.c	2013-10-31 17:45:23 +0000
@@ -54,6 +54,7 @@
 	link_t map_link;
 	/** List of fragments, @c reass_frag_t */
 	list_t frags;
+	void *data;
 } reass_dgram_t;
 
 /** One datagram fragment */
@@ -84,7 +85,6 @@
 {
 	reass_dgram_t *rdg;
 	int rc;
-
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_reass_queue_packet()");
 
 	fibril_mutex_lock(&reass_dgram_map_lock);
@@ -102,7 +102,7 @@
 	rc = reass_dgram_insert_frag(rdg, packet);
 	if (rc != EOK)
 		return ENOMEM;
-
+		
 	/* Check if datagram is complete */
 	if (reass_dgram_complete(rdg)) {
 		/* Remove it from the map */
@@ -197,6 +197,7 @@
 
 	frag->packet = *packet;
 	frag->packet.data = data_copy;
+	memcpy(data_copy, packet->data, packet->size);
 
 	/*
 	 * XXX Make resource-consuming attacks harder, eliminate any duplicate
@@ -208,20 +209,23 @@
 	 */
 
 	link = list_first(&rdg->frags);
-	while (link != NULL) {
+	while (link != NULL ) {
 		reass_frag_t *qf = list_get_instance(link, reass_frag_t,
 		    dgram_link);
 
 		if (qf->packet.offs >= packet->offs)
 			break;
-
-		link = link->next;
+		if ( link->next != &rdg->frags.head)
+			link = link->next;
+		else
+			break;
 	}
 
-	if (link != NULL)
+	if (link != NULL){
 		list_insert_after(&frag->dgram_link, link);
-	else
+	} else {
 		list_append(&frag->dgram_link, &rdg->frags);
+	}
 
 	return EOK;
 }
@@ -242,19 +246,21 @@
 	/* First fragment must be at offset zero */
 	frag = list_get_instance(list_first(&rdg->frags), reass_frag_t,
 	    dgram_link);
-	if (frag->packet.offs != 0)
+	if (frag->packet.offs != 0) {
 		return false;
+	}
 
 	prev = frag;
 	while (true) {
 		link = frag->dgram_link.next;
-		if (link == NULL)
+		if (link == NULL || link == (&rdg->frags.head))
 			return false;
 
 		/* Each next fragment must follow immediately or overlap */
 		frag = list_get_instance(link, reass_frag_t, dgram_link);
-		if (frag->packet.offs > prev->packet.offs + prev->packet.size)
+		if (frag->packet.offs > prev->packet.offs + prev->packet.size){
 			return false;
+		}
 
 		/* No more fragments - datagram is complete */
 		if (!frag->packet.mf)
@@ -306,13 +312,13 @@
 	dgram_size = frag->packet.offs + frag->packet.size;
 
 	/* Upper bound for fragment offset field */
-	fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
+	fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l+1);
 
 	/* Verify that total size of datagram is within reasonable bounds */
 	if (dgram_size > FRAG_OFFS_UNIT * fragoff_limit)
 		return ELIMIT;
 
-	dgram.data = calloc(dgram_size, 1);
+	dgram.data = rdg->data = calloc(dgram_size, 1);
 	if (dgram.data == NULL)
 		return ENOMEM;
 
@@ -333,15 +339,16 @@
 		ce = min(dgram_size, cfrag->packet.offs + cfrag->packet.size);
 
 		if (ce > cb) {
-			memcpy(dgram.data + cb,
+			memcpy(dgram.data + cb, cfrag->packet.data, cfrag->packet.size);
+
+/*			memcpy(dgram.data + cb,
 			    cfrag->packet.data + cb - cfrag->packet.offs,
-			    ce - cb);
+			    ce - cb);*/
 		}
 
 		if (!cfrag->packet.mf)
 			break;
 	}
-
 	return inet_recv_dgram_local(&dgram, proto);
 }
 
@@ -360,7 +367,7 @@
 		free(frag->packet.data);
 		free(frag);
 	}
-
+	free(rdg->data);
 	free(rdg);
 }
 

=== modified file 'uspace/srv/net/udp/assoc.c'
--- uspace/srv/net/udp/assoc.c	2013-09-12 21:26:18 +0000
+++ uspace/srv/net/udp/assoc.c	2013-10-31 17:45:23 +0000
@@ -274,11 +274,10 @@
 		return ENOMEM;
 
 	rc = udp_transmit_pdu(pdu);
+	udp_pdu_delete(pdu);
+
 	if (rc != EOK)
 		return EIO;
-
-	udp_pdu_delete(pdu);
-
 	return EOK;
 }
 
@@ -328,12 +327,15 @@
 	int rc;
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_received(%p, %p)", rsp, msg);
+	
+	//timeout assoc queue; in case of client crash
 
 	assoc = udp_assoc_find_ref(rsp);
 	if (assoc == NULL) {
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "No association found. Message dropped.");
 		/* XXX Generate ICMP error. */
 		/* XXX Might propagate error directly by error return. */
+		udp_msg_delete(msg);
 		return;
 	}
 

=== modified file 'uspace/srv/net/udp/msg.c'
--- uspace/srv/net/udp/msg.c	2012-03-30 19:55:01 +0000
+++ uspace/srv/net/udp/msg.c	2013-10-31 17:45:23 +0000
@@ -49,6 +49,7 @@
 /** Delete segment. */
 void udp_msg_delete(udp_msg_t *msg)
 {
+	free(msg->data);
 	free(msg);
 }
 

=== modified file 'uspace/srv/net/udp/pdu.c'
--- uspace/srv/net/udp/pdu.c	2013-09-29 21:06:10 +0000
+++ uspace/srv/net/udp/pdu.c	2013-10-31 17:45:23 +0000
@@ -196,8 +196,10 @@
 	if (nmsg == NULL)
 		return ENOMEM;
 
-	nmsg->data = text;
+	//nmsg->data = text;
 	nmsg->data_size = length - sizeof(udp_header_t);
+	nmsg->data = malloc(nmsg->data_size);
+	memcpy(nmsg->data, text, nmsg->data_size);
 
 	*msg = nmsg;
 	return EOK;

=== modified file 'uspace/srv/net/udp/udp_type.h'
--- uspace/srv/net/udp/udp_type.h	2013-09-12 21:26:18 +0000
+++ uspace/srv/net/udp/udp_type.h	2013-10-31 17:52:21 +0000
@@ -42,8 +42,7 @@
 #include <sys/types.h>
 #include <inet/addr.h>
 
-#define UDP_FRAGMENT_SIZE 4096
-
+#define UDP_FRAGMENT_SIZE 65535
 
 typedef enum {
 	UDP_EOK,

