diff -u -r -N ./net/Kconfig ./net/Kconfig
--- ./net/Kconfig	2007-10-28 13:47:49.000000000 +0100
+++ ./net/Kconfig	2007-10-28 13:52:34.000000000 +0100
@@ -32,6 +32,11 @@
 source "net/xfrm/Kconfig"
 source "net/iucv/Kconfig"
 
+config COR
+	bool "Connecion oriented routing"
+	---help---
+	  (no help avialable)
+
 config INET
 	bool "TCP/IP networking"
 	---help---
diff -u -r -N ./net/Makefile ./net/Makefile
--- ./net/Makefile	2007-10-28 13:47:47.000000000 +0100
+++ ./net/Makefile	2007-10-28 13:52:29.000000000 +0100
@@ -8,6 +8,7 @@
 obj-y	:= nonet.o
 
 obj-$(CONFIG_NET)		:= socket.o core/
+obj-$(CONFIG_COR)		+= cor/
 
 tmp-$(CONFIG_COMPAT) 		:= compat.o
 obj-$(CONFIG_NET)		+= $(tmp-y)
diff -u -r -N ./net/cor/Makefile ./net/cor/Makefile
--- ./net/cor/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/Makefile	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1 @@
+obj-y	 := common.o qdisc.o rcv.o snd.o sock.o packet_parse.o packet_gen.o
diff -u -r -N ./net/cor/common.c ./net/cor/common.c
--- ./net/cor/common.c	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/common.c	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1,213 @@
+#include "cor.h"
+
+struct binddir top;
+
+
+struct cell_hdr{
+	#warning odo init
+	spinlock_t lock;
+};
+
+
+inline int hdr_size()
+{
+	return (sizeof(struct cell_hdr) + sizeof(void *) - 1) / sizeof(void *);
+}
+
+inline int elements_per_cell(int cell_size)
+{
+	return cell_size/sizeof(void *) - hdr_size();
+}
+
+inline struct cell_hdr *cell_addr(struct htable *ht, u_int32_t id)
+{
+	int idx = (id%ht->htable_size) / (elements_per_cell(ht->cell_size));
+	return (struct cell_hdr *) (((char *)ht->htable) + ht->cell_size * idx);
+}
+
+inline struct htab_entry **element_addr(struct htable *ht, u_int32_t id)
+{
+	int idx = (id%ht->htable_size) % (elements_per_cell(ht->cell_size));
+	return ((struct htab_entry **)cell_addr(ht, id)) +
+			hdr_size()/sizeof(void *) + idx;
+}
+
+/*
+ *
+ * if *element == 0 ==> search and pop the packet from the htable
+ * else insert the packet into the htable
+ *
+ * return 1 if the element was found
+ */
+int search_htab(struct htable *ht, __u32 key, __u32 key_offset,
+		struct htab_entry **element)
+{
+	long iflags;
+
+	struct cell_hdr *hdr = cell_addr(ht, key);
+	struct htab_entry **curr = element_addr(ht, key);
+
+	BUG_TRAP(0 != key_offset%4);
+	BUG_TRAP(0 != curr);
+
+	spin_lock_irqsave( &(hdr->lock), iflags );
+
+	while (1) {
+		if (0 == *curr)
+			goto end;
+
+		if (((__u32 *)curr)[key_offset/4] == key)
+			goto found;
+
+		curr = &((*curr)->next);
+	}
+
+found:
+	if (0 == *element) {
+		*element = *curr;
+		*(curr) = (*curr)->next;
+	}
+	spin_unlock_irqrestore( &(hdr->lock), iflags );
+	return 1;
+end:
+	if (0 != *element) {
+		(*element)->next = (*curr)->next;
+		(*curr)->next = *element;
+	}
+	spin_unlock_irqrestore( &(hdr->lock), iflags );
+	return 0;
+}
+
+
+void init_htable(struct htable *ht)
+{
+	int num_cells;
+	BUG_TRAP(0 == ht);
+	ht->htable = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	ht->cell_size = 256;
+	num_cells = PAGE_SIZE/sizeof(void*)/ht->cell_size;
+	ht->htable_size = num_cells * elements_per_cell(ht->cell_size);
+	ht->num_elements = 0;
+}
+
+
+void bind(struct conn *conn, __u16 addrlen, __u8 *addr)
+{
+	struct binddir **curr;
+	unsigned long iflags;
+
+	if (0 == conn->bind_node) {
+		BUG_TRAP(conn->nextbindconn != 0 || conn->prevbindconn != 0);
+
+		spin_lock_irqsave( &(top.lock), iflags );
+		conn->bind_node = &top;
+		conn->nextbindconn = top.conns;
+		top.conns = conn;
+		spin_unlock_irqrestore( &(top.lock), iflags );
+	}
+
+	curr = &(conn->bind_node);
+
+	spin_lock_irqsave( &(conn->bind_node->lock), iflags );
+
+	while (*curr) {
+		if ((*curr)->addrlen == addrlen) {
+			if (0 == memcmp((*curr)->addr, addr, addrlen))
+				goto found;
+		}
+
+		curr = &((*curr)->next);
+	}
+
+	*curr = kmalloc(sizeof(struct binddir), GFP_KERNEL);
+	spin_lock_init( &((*curr)->lock) );
+	(*curr)->up = conn->bind_node;	
+	(*curr)->subdirs = 0;
+	(*curr)->next = 0;
+	(*curr)->prev = (struct binddir*)
+			(((char*)*curr) + offsetof(struct binddir, next));
+	if((*curr)->prev == (*curr)->up)
+		(*curr)->prev = 0;
+	(*curr)->owner = conn;
+	(*curr)->conns = 0;
+	(*curr)->addrlen = addrlen;
+	(*curr)->addr = kmalloc(sizeof(struct binddir), GFP_KERNEL);
+	memcpy((*curr)->addr, addr, addrlen);
+
+	goto out;
+found:
+	#warning todo review
+	if (0 != conn->prevbindconn) {
+		BUG_TRAP(conn->bind_node->conns == conn);
+		conn->prevbindconn->nextbindconn = conn->nextbindconn;
+		conn->nextbindconn->prevbindconn = conn->prevbindconn;
+	} else {
+		BUG_TRAP(conn->bind_node->conns != conn);
+		conn->bind_node->conns = conn->nextbindconn;
+	}
+	conn->prevbindconn = conn->nextbindconn = 0;
+	
+	conn->bind_node = *curr;
+	conn->nextbindconn = (*curr)->conns;
+	(*curr)->conns = conn;
+
+out:
+	spin_unlock_irqrestore( &(conn->bind_node->lock), iflags );
+}
+
+int multicast(struct conn *conn)
+{
+	int ret;
+	unsigned long iflags;
+
+	BUG_TRAP(0 == conn);
+	BUG_TRAP(conn->bind_node == &top);
+
+	spin_lock_irqsave( &(conn->bind_node->lock), iflags );
+	#warning todo owner
+	if (0 == conn->bind_node->conns) {
+		conn->bindtype = BINDTYPE_MCAST;
+		conn->bind_node->conns = conn;
+		#warning todo ret_ok
+	} else{
+		#warning todo ret_error
+	}
+	spin_unlock_irqrestore( &(conn->bind_node->lock), iflags );
+	return ret;
+}
+
+int listen(struct conn *conn)
+{
+	int ret;
+	unsigned long iflags;
+
+	BUG_TRAP(conn == 0);
+	BUG_TRAP(conn->bind_node == &top);
+
+	spin_lock_irqsave( &(conn->bind_node->lock), iflags );
+	#warning todo owner
+	if (0 == conn->bind_node->conns) {
+		conn->bindtype = BINDTYPE_LISTEN;
+		conn->bind_node->conns = conn;
+		#warning todo ret_ok
+	} else {
+		#warning todo ret_error
+	}
+	spin_unlock_irqrestore( &(conn->bind_node->lock), iflags );
+}
+
+int connect(struct conn *conn)
+{
+}
+
+int connect_success(struct conn *conn)
+{
+}
+
+void dec_connrefs(struct conn *conn)
+{
+	atomic_dec(&(conn->refs));
+	#warning todo free
+}
+
+MODULE_LICENSE("GPL");
diff -u -r -N ./net/cor/cor.h ./net/cor/cor.h
--- ./net/cor/cor.h	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/cor.h	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1,570 @@
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <asm-sh/kgdb.h>
+#include <linux/spinlock.h>
+
+/* psched_time_t */
+#include <net/pkt_sched.h>
+
+
+#define ETH_P_COR 0x1022
+
+
+/*
+ * speedinfo[2] =
+ *     buffer_state_value = speedinfo % 181
+ *     speed_value = speedinfo / 181
+ *
+ *     buffer_state = 1024 * pow(2, buffer_state_value/3.0)
+ *     speed = 1024 * pow(2, speed_value/12.0)
+ *   see the .0 ...
+ *
+ * This has to be done either with floating points (which is no so nice) or
+ * you can calculate:
+ *     buffer_state =  pow(2, value/3) *
+ *         1024 * pow(pow(2, 1.0/3), buffer_state_value%3)
+ *   where 1024 * pow(pow(2, 1.0/4), value%3) can be just a table lookup
+ *   (the "1024" should be part of the value in the table, because it increases
+ *   the accuracy)
+ *
+ *   you can do the same with the speed
+ *
+ *
+ * Some values have special meanings:
+ *   if speedinfo is the highest possible value(65535), it means both values are
+ *     inifinite
+ *   if buffer_state_value if > 91, you have to subtract 90 and make the
+ *     resulting buffer_state negative
+ */
+
+
+/*
+ * packet_id_definition =
+ *   packet_id_def_count[2] (only on (N)ACK)
+ *   num_new_packet_ids[1]
+ *   new_packet_id[num_new_packet_ids][4]
+ *
+ * packet_id_def_count = counter of the definition os this connection
+ *   this is neccesary to ensure that the other side recieves the packet ids
+ *   int the correct order
+ */
+
+/*
+ * bindaddr =
+ * addrlen[2] addr[addrlen]
+ */
+
+/* PADDING[1] */
+#define PADDING 1
+
+/* ACK1[1] sent_packet_id[4] */
+#define ACK1 2
+
+/* ACK2[1] sent_packet_id[4] speedinfo[2] */
+#define ACK2 3
+
+/* ACK3[1] sent_packet_id[4] packet_id_definition */
+#define ACK3 4
+
+/* ACK4[1] sent_packet_id[4] speedinfo[2], packet_id_definition */
+#define ACK4 5
+
+/* see ACK[1-4] */
+#define NACK1 6
+#define NACK2 7
+#define NACK3 8
+#define NACK4 9
+
+/*
+ * incoming connection, the packet_id_definition is our send channel
+ * CONNECT[1] packet_id_definition */
+#define CONNECT 10
+
+/*
+ * incoming connection successful, packet_id_definition is our receive channel
+ * CONNECT_SUCCESS[1] packet_id[4] packet_id_definition */
+#define CONNECT_SUCCESS 11
+
+/* CONNECT_FAILED_*[1] packet_id[4] */
+#define CONNECT_FAILED_TEMP 12
+#define CONNECT_FAILED_PERM 13
+
+
+/*
+ * The BIND messages should rather be connection data,
+ * not kernel packets.
+ */
+
+
+/* BIND[1] packet_id[4] num_binds[1] bindaddr */
+#define BIND 14
+
+/* BIND_MCAST[1] packet_id[4] */
+#define BIND_MCAST 15
+
+/* BIND_LISTEN[1] packet_id[4] */
+#define BIND_LISTEN 16
+
+/*
+ * outgoing connection
+ * BIND_CONNET[1] packet_id[4] */
+#define BIND_CONNECT 18
+
+
+/*
+ * FLUSH_CONN_BUF[1] packet_id[4] offset[2]
+ * (flush until offset bytes after the beginning of the packet)
+ */
+#define FLUSH_CONN_BUF 19
+
+/* CONN_DATA[1] packet_id[4] length[2] data[length] */
+#define CONN_DATA 20
+
+/* CONN_CLOSE[1] packet_id[4] */
+#define CONN_EOF 21
+
+/*
+ * { CONN_RESET_FW[1] packet_id[4] }
+ * We send this, if there is an established connection we want to close.
+ */
+#define CONN_RESET_FW 22
+
+/* 
+ * { CONN_RESET_BW[1] sent_packet_id[4] } 
+ * This is the response we send when we receive a packet with an invalid
+ * packet_id. Note that when receiving the packet_id needs to be looked up
+ * in the list of packet_ids we send to this neighbor, not in the packet_id
+ * list for routing the packet"
+ */
+#define CONN_RESET_BW 23
+
+
+/* result codes for rcv.c/proc_packet */
+#define RC_DROP 0
+#define RC_FINISHED 1
+
+#define RC_RCV1_ANNOUNCE 2
+#define RC_RCV1_KERNEL 3
+#define RC_RCV1_CONN 4
+
+struct htab_entry{
+	struct htab_entry *next;
+};
+
+struct htable{
+	struct htab_entry **htable;
+	__u32 htable_size;
+	__u32 cell_size;
+	__u32 num_elements;
+};
+
+struct conn;
+
+/* not sent over the network - internal meansing only */
+#define MSGTYPE_ACK 1
+#define MSGTYPE_CONNECT 2
+#define MSGTYPE_BINDMCAST 3
+#define MSGTYPE_BINDLISTEN 4
+#define MSGTYPE_BINDCONNECT 5
+#define MSGTYPE_FLUSH_BUF 6
+#define MSGTYPE_EOF 7
+#define MSGTYPE_RESET 8
+#define MSGTYPE_RESET_BW 9
+
+
+struct control_msg{
+	struct neighbor *nb;
+	struct control_msg *next;
+	__u8 type;
+	union{
+		struct{
+			__u32 packet_id;
+			struct conn *conn;
+		}ack;
+		
+		struct{
+			struct conn *conn;
+		}connect;
+		
+		/* bind_*: packet_id has to be first (see packet_gen.c) */
+		struct{
+			__u32 packet_id;
+			struct conn *conn;
+		}bind_mcast;
+		
+		struct{
+			__u32 packet_id;
+			struct conn *conn;
+		}bind_listen;
+		
+		struct{
+			__u32 packet_id;
+			struct conn *conn;
+		}bind_connect;
+				
+		struct{
+			__u16 offset;
+			__u32 packet_id;
+			struct conn *conn;
+		}flush_buf;
+		
+		struct{
+			struct conn *conn;
+		}eof;
+		
+		struct{
+			__u32 packet_id;
+			struct conn *conn;
+		}reset;
+		
+		struct{
+			__u32 sent_packet_id;
+		}reset_bw;
+	}msg;
+	__u32 timedue;
+};
+
+struct neighbor{
+	struct neighbor *next;
+	struct neighbor *prev;
+	
+	struct net_device *dev;
+	char mac[6];
+	
+	#warning semaphore/mutex?, TODO:timer
+	struct timer_list cmsg_timer;
+	spinlock_t cmsg_lock;
+	struct control_msg *first_cm;
+	struct control_msg *last_cm;
+	__u32 timedue;
+	__u32 length;
+	
+	__u32 ooo_packets;
+	
+	__u32 latency;
+	
+	
+	/*
+	 * connecions which receive data from/send data to this node
+	 * used when terminating all connections of a neighbor
+	 */
+	struct conn *rcv;
+	struct conn *snd;
+	
+	/* 
+	 * the timer has to be inited when adding the neighbor
+	 * init_timer(struct timer_list * timer);
+	 * add_timer(struct timer_list * timer);
+	 */
+	spinlock_t retrans_lock;
+	struct timer_list retrans_timer;
+	
+	/* 
+	 * next_retransmit are linked with
+	 * skb_procstate->funcstate.retransmit_queue
+	 * because the sk_buff next/prev fields are needed by the hashtable
+	 */
+	struct sk_buff *first_retransmit;
+	struct sk_buff *last_retransmit;
+	struct htable all_retransmits;
+};
+
+struct packet_id_in {
+	struct htab_entry entry;
+	struct conn *conn;
+	struct sk_buff *skb;
+	struct packet_id_in *next;
+	__u32 packet_id;
+};
+
+struct packet_id_out {
+	struct packet_id_out *next;
+	__u32 num_ids;
+	__u32 offset;
+	/* __u32 packet_ids[num_ids] attached */
+};
+
+struct conn_qdisc_info;
+
+/*
+ * When deleting an element from the list, we can simply do
+ * el->next->prev=el->prev; el->prev->next=el->next;
+ * This is because the struct conn_qdisc_list is just another element in the
+ * list. If the list is empty both "first" and "last" points to itself.
+ */
+struct conn_qdisc_list{
+	struct conn_qdisc_info *first;
+	struct conn_qdisc_info *last;
+};
+
+struct conn_qdisc_listelement{
+	struct conn_qdisc_info *next;
+	struct conn_qdisc_info *prev;
+};
+
+struct cor_sched_data{
+	/* This struct has to be first! See cor.h */
+	struct conn_qdisc_list cql;
+
+	spinlock_t lock;
+};
+
+/* see qdisc.c */
+struct conn_qdisc_info{
+	/* This has to be first! */
+	struct conn_qdisc_listelement le;
+
+	spinlock_t lock;
+	
+	struct sk_buff_head queue;
+	
+	psched_time_t last_rcv_time;
+	psched_time_t last_snd_time;
+//	PSCHED_GET_TIME(now);
+	
+	__u32 bytes_queued;
+	__u32 bytes_queued_avg;
+
+	/* state */
+	__u32 credits;
+	
+	/* per second */
+	__u32 credit_in;
+	__u32 credit_out;
+	
+	/* credit status of the sender/recp (for balancing credits)*/
+	__u32 credit_sender;
+	__u32 credit_recp;
+	
+	__u32 avg_snd_cost;
+	
+	__u32 avg_rate;
+	
+	__u8 	credit_flowdirection:2,
+		qdisc_active:1;
+};
+
+/* these are the non sent, non resized packets */
+struct resize_buf{
+	spinlock_t lock;
+	__u32 totalsize;
+	struct sk_buff *skb_first;
+	struct sk_buff *skb_last;
+};
+
+struct conn{
+	/* when zero we can free this struct */
+	atomic_t refs;
+	// = ATOMIC_INIT(0);
+
+
+#define SOURCE_CONN 1
+#define SOURCE_IN 2
+#define SOURCE_SOCK 3
+
+#define TARGET_MULTIPLE 1
+#define TARGET_OUT 2
+#define TARGET_SOCK 3
+#define TARGET_KERNEL 4
+	__u8	sourcetype:4,
+		targettype:4;
+	
+	
+#define BINDTYPE_BIND 0
+#define BINDTYPE_LISTEN 1
+#define BINDTYPE_MCAST 2
+#define BINDTYPE_CONNECTED 3
+	__u8	bindtype;
+	
+	struct binddir *bind_node;
+	struct conn *nextbindconn;
+	struct conn *prevbindconn;
+	
+	union{
+		/* from another conn with targettype out_multiple */
+		struct{
+			struct conn *src;
+			/* "linked" list of multiple targets */
+			struct conn *next;
+			struct conn *prev;
+		}conn;
+		
+		struct{
+			struct neighbor *nb;
+			/* list of all connections from this neighbor */
+			struct conn *next;
+			struct conn *prev;
+			
+			struct packet_id_in *next_packet_id;
+			
+			spinlock_t reorder_lock;
+			
+			__u32 ooo_packets;
+		}in;
+		
+		struct{
+			wait_queue_head_t *wait;
+			struct sk_buff_head queue;
+		}sock;
+	}source;
+	
+	union{
+		struct{
+			struct conn *firsttarget;
+			__u32 numtargets;
+		}multiple;
+		
+		struct{
+			/* has to be first (because it is first in kernel) */
+			struct neighbor *nb;
+			/* list of all connections to this neighbor */
+			struct conn *next;
+			struct conn *prev;
+			
+			spinlock_t pid_lock;
+			struct packet_id_out *next_pid;
+			struct packet_id_out *last_pid;
+			/* see packet id definition */
+			__u16 last_packet_id_cnt;
+			__u8 packet_id_sent:1;
+			
+			struct resize_buf rb;		
+			struct conn_qdisc_info qi;
+		}out;
+		
+		struct{
+			struct sk_buff_head *queue;
+			wait_queue_head_t *wait;
+			spinlock_t lock;
+		}sock;
+		
+		struct{
+			struct neighbor *nb;
+		}kernel;
+	}target;
+	
+	struct conn *reverstdir;
+};
+
+struct binddir{
+	spinlock_t lock;
+	
+	struct listenerdir *up;
+	
+	struct listenerdir *subdirs;
+
+	struct listenerdir *next;
+	struct listenerdir *prev;
+	
+	struct conn *owner;
+	
+	struct conn *conns;
+
+	__u16 addrlen;
+	__u8 *addr;
+};
+
+/* inside skb->cb */
+struct skb_procstate{
+
+	struct conn *conn;
+
+	/**
+	 *
+	 * old???
+	 * Packets generated from resizing:
+	 * packet_id packet_id: the first packet used to assemble this packet
+	 * next_packet_id: the first received packet which is *not* fully stored
+	 *   in this skb (maybe it isn't stored in this packet at all)
+	 */
+	
+	union{
+		#warning free!
+		struct packet_id_in *in;
+		
+		struct{
+			struct sk_buff *next;
+			struct sk_buff *prev;
+			__u32 timeout;
+			__u32 sent_pid;
+		}retransmit_queue;
+		
+		struct{
+			__u32 credits_used;/* for requeueing */
+		}out;
+	}funcstate;
+};
+
+
+static inline struct skb_procstate* skb_pstate(struct sk_buff **skb)
+{
+	return (struct skb_procstate *) &((*skb)->cb[0]);
+}
+
+
+static inline __u32 mss(struct neighbor *nb)
+{
+	return nb->dev->mtu - LL_RESERVED_SPACE(nb->dev) - 4;
+}
+
+
+extern struct htable pid_table;
+
+static inline struct packet_id_in* get_packet_id(__u32 packet_id)
+{
+	struct packet_id_in *ret = 0;
+	__u32 offset = offsetof(struct packet_id_in, packet_id);
+
+	search_htab(&pid_table, packet_id, offset, (struct htab_entry**)&ret);
+
+	return ret;
+}
+
+
+/* common.c */
+extern int search_htab(struct htable *ht, __u32 key, __u32 key_offset,
+		struct htab_entry **element);
+
+extern void init_htable(struct htable *ht);
+
+extern void bind(struct conn *conn, __u16 addrlen, __u8 *addr);
+
+extern int multicast(struct conn *conn);
+
+extern int listen(struct conn *conn);
+
+extern int connect(struct conn *conn);
+
+extern int connect_success(struct conn *conn);
+
+extern void dec_connrefs(struct conn *conn);
+
+/* rcv.c */
+extern int put_packet_id_def(struct sk_buff *skb, struct conn *conn,
+		int spaceleft);
+
+/* packet_parse.c */
+extern void kernel_packet(struct sk_buff *skb);
+
+/* packet_gen.c */
+extern void flush(struct conn *conn, __u16 offset, __u32 timeout);
+
+extern void eof(struct conn *conn, __u32 timeout);
+
+extern void reset(struct conn *conn);
+
+extern void reset_bw(struct neighbor *nb, __u32 packet_id);
+
+extern void send_ack(struct neighbor *nb, __u32 packet_id);
+
+/* snd.c */
+extern struct sk_buff* create_packet(struct conn *target, int size,
+		int alloc_flags);
+
+extern void send_packet(struct sk_buff *skb);
+
+extern struct conn *ack_received(struct neighbor *nb, __u32 packet_id,
+		int nack);
+
+extern struct conn *nack_received(struct neighbor *nb, __u32 packet_id);
diff -u -r -N ./net/cor/packet_gen.c ./net/cor/packet_gen.c
--- ./net/cor/packet_gen.c	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/packet_gen.c	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1,311 @@
+#include "cor.h"
+#include "settings.h"
+
+
+static int add_ack(struct sk_buff *skb, struct control_msg *cm, int spaceleft)
+{
+	int rc;
+
+	char *dst;
+
+	char *pid = (char *) &(cm->msg.ack.packet_id);
+
+	if (spaceleft < 5)
+		return 0;
+
+	dst = skb_put(skb, 5);
+	BUG_TRAP(0 == dst);
+
+	rc = put_packet_id_def(skb, cm->msg.ack.conn, spaceleft - 5);
+
+	dst[0] = rc == 0 ? ACK1 : ACK3;
+	dst[1] = pid[0];
+	dst[2] = pid[1];
+	dst[3] = pid[2];
+	dst[4] = pid[3];
+
+	return 5 + rc;
+}
+
+static int add_connect(struct sk_buff *skb, struct control_msg *cm,
+		int spaceleft)
+{
+	int rc;
+
+	char *dst;
+
+	if (spaceleft < 2 + PACKET_IDS_ON_CONNECT * 4)
+		return 0;
+
+	dst = skb_put(skb, 1);
+	BUG_TRAP(0 == dst);
+
+	dst[0] = CONNECT;
+
+	rc = put_packet_id_def(skb, cm->msg.connect.conn, spaceleft - 1);
+
+	return 1 + rc;
+}
+
+static int add_bind(struct sk_buff *skb, struct control_msg *cm,
+		int spaceleft)
+{
+	char *dst;
+
+	char *pid = (char *) &(cm->msg.bind_mcast.packet_id);
+
+	if (spaceleft < 5)
+		return 0;
+
+	dst = skb_put(skb, 1);
+	BUG_TRAP(0 == dst);
+
+	switch (cm->type) {
+	case MSGTYPE_BINDMCAST:
+		dst[0] = BIND_MCAST;
+		break;
+	case MSGTYPE_BINDLISTEN:
+		dst[0] = BIND_LISTEN;
+		break;
+	case MSGTYPE_BINDCONNECT:
+		dst[0] = BIND_CONNECT;
+		break;
+	default:
+		BUG();
+	}
+
+	dst[1] = pid[0];
+	dst[2] = pid[1];
+	dst[3] = pid[2];
+	dst[4] = pid[3];
+
+	return 5;
+}
+
+static int add_flush_buf(struct sk_buff *skb, struct control_msg *cm,
+		int spaceleft)
+{
+	char *dst;
+
+	char *pid = (char *) &(cm->msg.bind_listen.packet_id);
+	__u16 offset = ntohs(cm->msg.flush_buf.offset);
+
+	if (spaceleft < 7)
+		return 0;
+
+	dst = skb_put(skb, 7);
+	BUG_TRAP(0 == dst);
+
+	dst[0] = FLUSH_CONN_BUF;
+	dst[1] = pid[0];
+	dst[2] = pid[1];
+	dst[3] = pid[2];
+	dst[4] = pid[3];
+	dst[5] = ((char *)(&offset))[0];
+	dst[6] = ((char *)(&offset))[1];
+
+	return 7;
+}
+
+static int add_eof(struct sk_buff *skb, struct control_msg *cm, int spaceleft)
+{
+	#warning todo
+}
+
+static int add_reset(struct sk_buff *skb, struct control_msg *cm, int spaceleft)
+{
+	char *dst;
+
+	char *pid = (char *) &(cm->msg.reset.packet_id);
+
+	if (spaceleft < 5)
+		return 0;
+
+	dst = skb_put(skb, 5);
+	BUG_TRAP(0 == dst);
+
+	dst[0] = CONN_RESET_FW;
+	dst[1] = pid[0];
+	dst[2] = pid[1];
+	dst[3] = pid[2];
+	dst[4] = pid[3];
+
+	return 5;
+}
+
+static int add_reset_bw(struct sk_buff *skb, struct control_msg *cm,
+		int spaceleft)
+{
+	char *dst;
+
+	char *pid = (char *) &(cm->msg.reset_bw.sent_packet_id);
+
+	if (spaceleft < 5)
+		return 0;
+
+	dst = skb_put(skb, 5);
+	BUG_TRAP(0 == dst);
+
+	dst[0] = CONN_RESET_BW;
+	dst[1] = pid[0];
+	dst[2] = pid[1];
+	dst[3] = pid[2];
+	dst[4] = pid[3];
+
+	return 5;
+}
+
+
+static int add_message(struct sk_buff *skb, struct control_msg *cm,
+		int spaceleft)
+{
+	switch (cm->type) {
+	case MSGTYPE_ACK:
+		return add_ack(skb, cm, spaceleft);
+	case MSGTYPE_CONNECT:
+		return add_connect(skb, cm, spaceleft);
+	case MSGTYPE_BINDMCAST:
+	case MSGTYPE_BINDLISTEN:
+	case MSGTYPE_BINDCONNECT:
+		return add_bind(skb, cm, spaceleft);
+	case MSGTYPE_FLUSH_BUF:
+		return add_flush_buf(skb, cm, spaceleft);
+	case MSGTYPE_EOF:
+		return add_eof(skb, cm, spaceleft);
+	case MSGTYPE_RESET:
+		return add_reset(skb, cm, spaceleft);
+	case MSGTYPE_RESET_BW:
+		return add_reset_bw(skb, cm, spaceleft);
+	default:
+		BUG();
+	}
+}
+
+static void padding(struct sk_buff *skb, int length)
+{
+	char dst = skb_put(skb, length);
+	BUG_TRAP(0 == dst);
+	memset(dst, PADDING, length);
+}
+
+static void send_messages(struct neighbor *nb, struct sk_buff *skb,
+		int spaceleft)
+{
+	long iflags;
+	int length = 0;
+	struct control_msg *old;
+
+	while (0 != nb->first_cm) {
+		int rc = add_message(skb, nb->first_cm, spaceleft - length);
+		if (0 == rc)
+			goto send_packet;
+		length += rc;
+		old = nb->first_cm;
+		nb->first_cm = nb->first_cm->next;
+		kfree(old);
+	}
+
+	nb->last_cm = 0;
+send_packet:
+	nb->length -= length;
+
+	padding(skb, spaceleft - length);
+	send_packet(skb);
+}
+
+static void controlmsg_timerfunc(unsigned long arg)
+{
+	unsigned long iflags;
+
+	struct neighbor *nb = (struct neighbor *) arg;
+	
+	int targetmss = mss(nb);
+	int size = targetmss;
+
+	struct sk_buff *skb;
+	struct control_msg *curr;
+
+	int sent = 0;
+
+	spin_lock_irqsave( &(nb->cmsg_lock), iflags );
+
+	while (nb->length >= targetmss) {
+send:
+		sent = 1;
+		/* skb = create_packet */
+		send_messages(nb, skb, size);
+	}
+
+	curr = nb->first_cm;
+
+	while (1 == sent && 0 != curr) {
+		if (time_before_eq(curr->timedue, jiffies))
+			goto send;
+		else if (time_before(curr->timedue, nb->timedue))
+			nb->timedue = curr->timedue;
+
+		curr = curr->next;
+	}
+
+	spin_unlock_irqrestore( &(nb->cmsg_lock), iflags );
+
+	mod_timer(&(nb->cmsg_timer), nb->timedue);
+}
+
+static void add_control_msg(struct control_msg *msg, __u32 length,
+		struct neighbor *nb)
+{
+	long iflags;
+	spin_lock_irqsave( &(nb->cmsg_lock), iflags );
+
+	if (msg == 0)
+		goto length;
+
+	if (unlikely(0 == nb->first_cm)) {
+		BUG_TRAP(0 != nb->last_cm);
+		nb->first_cm = nb->last_cm = msg;
+	} else { 
+		nb->last_cm->next = msg;
+		nb->last_cm = msg;
+	}
+
+	if (unlikely(time_before(msg->timedue, nb->timedue))) {
+		nb->timedue = msg->timedue;
+		mod_timer(&(nb->cmsg_timer), nb->timedue);
+	}
+
+length:
+	nb->length += length;
+	/*if (unlikely(nb->length >= mss(nb)))
+		send_contol_msgs(nb);*/
+
+	spin_unlock_irqrestore( &(nb->cmsg_lock), iflags );
+}
+
+
+void flush(struct conn *conn, __u16 offset, __u32 timeout)
+{
+
+}
+
+void eof(struct conn *conn, __u32 timeout)
+{
+
+}
+
+void reset(struct conn *conn)
+{
+	struct control_msg *cm = kmalloc(sizeof(struct control_msg),
+			GFP_KERNEL);
+	cm->type = MSGTYPE_RESET;
+	cm->msg.reset.conn = conn;
+	#warning todo pid, send
+}
+
+void reset_bw(struct neighbor *nb, __u32 packet_id)
+{
+}
+
+void send_ack(struct neighbor *nb, __u32 packet_id)
+{
+}

diff -u -r -N ./net/cor/packet_parse.c ./net/cor/packet_parse.c
--- ./net/cor/packet_parse.c	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/packet_parse.c	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1,283 @@
+#include "cor.h"
+
+static void set_speed(struct conn *conn, __u16 speedinfo)
+{
+}
+
+static void add_packet_ids(struct conn *conn, struct sk_buff *skb)
+{
+}
+
+static void parse_ack(struct neighbor *nb, struct sk_buff *skb, __u8 code)
+{
+	__u32 *packet_id_ptr;
+	__u32 packet_id;
+	
+	struct conn *conn;
+				
+	packet_id_ptr = (__u32 *) skb_pull(skb, 4);
+	BUG_TRAP(packet_id_ptr == 0);
+	packet_id = ntohl(*packet_id_ptr);
+	
+	if (likely(code == ACK1 || code == ACK2 || code == ACK3 ||
+			code == ACK4)) {
+		conn = ack_received(nb, packet_id, 0);
+	} else if (code == NACK1 || code == NACK2 || code == NACK3 ||
+			code == NACK4) {
+		conn = ack_received(nb, packet_id, 1);
+	} else{
+		BUG();
+	}
+
+	if (unlikely(code == ACK2 || code == ACK4 || code == NACK2 ||
+			code == NACK4)) {
+		__u16 *speedinfo_ptr = (__u16 *) skb_pull(skb, 2);
+		__u16 speedinfo = ntohs (*speedinfo_ptr);
+		set_speed(conn, speedinfo);
+	}
+
+	if (unlikely(code == ACK3 || code == ACK4 || code == NACK3 ||
+			code == NACK4)) {
+		add_packet_ids(conn, skb);
+	}
+}
+
+static void parse_bind(struct sk_buff *skb, struct conn *conn)
+{
+	__u8 *num_binds_ptr = skb_pull(skb, 1);
+	__u8 num_binds;
+	BUG_TRAP(num_binds_ptr == 0);
+	num_binds = *num_binds_ptr;
+	for (; num_binds > 0;num_binds--) {
+		__u16 *addrlen_ptr = (__u16 *) skb_pull(skb, 2);
+		__u16 addrlen;
+		__u8 *addr;
+		BUG_TRAP(addrlen_ptr == 0);
+		addrlen = ntohs(*addrlen_ptr);
+		addr = skb_pull(skb, addrlen);
+		BUG_TRAP(addr == 0);
+		bind(conn, addrlen, addr);
+	}
+}
+
+
+void kernel_packet2(struct sk_buff *skb)
+{
+	struct skb_procstate *ps = skb_pstate(&skb);
+	struct neighbor *nb = ps->conn->target.kernel.nb;
+	int ack = 0;
+	while (1) {
+		__u32 *packet_id_ptr;
+		__u32 packet_id;
+		struct packet_id_in *pid;
+
+		__u8 *codeptr = skb_pull(skb, 1);
+		__u8 code;
+		BUG_TRAP(codeptr == 0);
+		code = *codeptr;
+
+		switch (code) {
+		case PADDING:
+			break;
+		case ACK1:
+		case ACK2:
+		case ACK3:
+		case ACK4:
+		case NACK1:
+		case NACK2:
+		case NACK3:
+		case NACK4:
+			parse_ack(nb, skb, code);
+			break;
+		case CONNECT:
+			#warning todo create conn/add_packet_ids
+			break;
+		case CONNECT_SUCCESS:
+			#warning todo create reverse dir connection
+			break;
+		case CONNECT_FAILED_TEMP:
+		case CONNECT_FAILED_PERM:
+			#warning todo
+			break;
+		case BIND:
+		case BIND_MCAST:
+		case BIND_LISTEN:
+		case BIND_CONNECT:
+		case FLUSH_CONN_BUF:
+		case CONN_DATA:
+		case CONN_EOF:
+			#warning todo is next packet?
+			#warning todo move to next packet
+			packet_id_ptr = (__u32 *) skb_pull(skb, 4);
+			BUG_TRAP(packet_id_ptr == 0);
+			packet_id = ntohl(*packet_id_ptr);
+			pid = get_packet_id(packet_id);
+			if (code == BIND)
+				parse_bind(skb, pid->conn);
+			else if (code == BIND_MCAST)
+				multicast(pid->conn);
+			else if (code == BIND_LISTEN)
+				multicast(pid->conn);
+			else if (code == BIND_CONNECT)
+				multicast(pid->conn);
+			else if (code == FLUSH_CONN_BUF)
+				#warning todo offset, timeout
+				flush(pid->conn, 0, 10);
+			else if (code == CONN_DATA) {
+				#warning todo
+				//skb_trim(skb, len);
+			} else if (code == CONN_EOF)
+				#warning todo timeout
+				eof(pid->conn, 10);
+			else if (code == CONN_RESET_FW)
+				reset(pid->conn);
+			else
+				BUG();
+			kfree(pid);
+			break;
+		case CONN_RESET_BW:
+			packet_id_ptr = (__u32 *) skb_pull(skb, 4);
+			BUG_TRAP(packet_id_ptr == 0);
+			packet_id = ntohl(*packet_id_ptr);
+			reset_bw(nb, packet_id);
+			break;
+		default:
+			BUG();
+		}
+	}
+
+	if (ack)
+		send_ack(nb, ps->funcstate.in->packet_id);
+}
+
+static int bind_length(struct sk_buff *skb2)
+{
+	int u;
+	__u8 *num_binds = skb_pull(skb2, 1);
+	if (num_binds == 0)
+		return 1;
+	for (u=0; u < (*num_binds); u++) {
+		__u16 *lenptr = (__u16 *) skb_pull(skb2, 2);
+		__u16 len;
+		__u8 *addr;
+		if (lenptr == 0)
+			return 1;
+		len = ntohs(*lenptr);
+		addr = skb_pull(skb2, len);
+		if (addr == 0)
+			return 1;
+	}
+	return 0;
+}
+
+static int packet_id_def_length(struct sk_buff *skb2)
+{
+	__u8 *num_ids = skb_pull(skb2, 1);
+	__u8 *ids;
+	if (num_ids == 0)
+		return 1;
+	ids = skb_pull(skb2, 4 * (*num_ids));
+	if (ids == 0)
+		return 1;
+	return 0;
+}
+
+void kernel_packet(struct sk_buff *skb)
+{
+	struct sk_buff *skb2 = skb_clone(skb, __GFP_DMA | GFP_KERNEL);
+
+	while (1) {
+		__u8 *codeptr = skb_pull(skb2, 1);
+		__u8 code;
+
+		__u8 *lengthptr;
+		__u8 length;
+
+		if (codeptr == 0)
+			goto discard;
+		code = *codeptr;
+		switch (code) {
+		case PADDING:
+			break;
+		case ACK1:
+		case NACK1:
+			if (skb_pull(skb2, 4) == 0)
+				goto discard;
+			break;
+		case ACK2:
+		case NACK2:
+			if (skb_pull(skb2, 6) == 0)
+				goto discard;
+			break;
+		case ACK3:
+		case NACK3:
+			if (skb_pull(skb2, 4) == 0)
+				goto discard;
+			if (packet_id_def_length(skb2))
+				goto discard;
+			break;
+		case ACK4:
+		case NACK4:
+			if (skb_pull(skb2, 6) == 0)
+				goto discard;
+			if (packet_id_def_length(skb2))
+				goto discard;
+			break;
+		case CONNECT:
+			if (packet_id_def_length(skb2))
+				goto discard;
+			break;
+		case CONNECT_SUCCESS:
+			if (skb_pull(skb2, 4) == 0)
+				goto discard;
+			if (packet_id_def_length(skb2))
+				goto discard;
+			break;
+		case CONNECT_FAILED_TEMP:
+		case CONNECT_FAILED_PERM:
+			if (skb_pull(skb2, 4) == 0)
+				goto discard;
+			break;
+		case BIND:
+			if (skb_pull(skb2, 4) == 0)
+				goto discard;
+			if (bind_length(skb2))
+				goto discard;
+			break;
+		case BIND_MCAST:
+		case BIND_LISTEN:
+		case BIND_CONNECT:
+			if (skb_pull(skb2, 4) == 0)
+				goto discard;
+			break;
+		case FLUSH_CONN_BUF:
+			if (skb_pull(skb2, 9) == 0)
+				goto discard;
+			break;
+		case CONN_DATA:
+			if (skb_pull(skb2, 4) == 0)
+				goto discard;
+			lengthptr = skb_pull(skb2, 2);
+			if (lengthptr == 0)
+				goto discard;
+			length = ntohs(*lengthptr);
+			if (skb_pull(skb, length) == 0)
+				goto discard;
+			break;
+		case CONN_EOF:
+		case CONN_RESET_FW:
+		case CONN_RESET_BW:
+			if (skb_pull(skb2, 4) == 0)
+				goto discard;
+			break;
+		default:
+			goto discard;
+		}
+	}
+	kfree_skb(skb2);
+	kernel_packet2(skb);
+	kfree_skb(skb);
+discard:
+	kfree_skb(skb2);
+	kfree_skb(skb);
+}
diff -u -r -N ./net/cor/packet_parse.s ./net/cor/packet_parse.s
--- ./net/cor/packet_parse.s	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/packet_parse.s	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1 @@
+	.file	"packet_parse.c"
diff -u -r -N ./net/cor/qdisc.c ./net/cor/qdisc.c
--- ./net/cor/qdisc.c	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/qdisc.c	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1,195 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <net/pkt_sched.h>
+#include <net/inet_ecn.h>
+
+#include "cor.h"
+#include "settings.h"
+
+struct cor_qdisc_opts{
+	//none???
+};
+
+
+static struct sk_buff * cor_dequeue(struct Qdisc *sch)
+{
+	struct sk_buff *ret;
+
+	struct cor_sched_data *q = qdisc_priv(sch);
+
+	struct conn_qdisc_info *curr = q->cql.first;
+	struct conn_qdisc_info *best = curr;
+
+	__u64 currcost_limit = 0;
+	__u64 currcost = 0;
+
+	spin_lock(&(q->lock));//irqsave???
+
+	while (curr != 0) {
+		__u32 max1 = (256 * ((__u64)curr->credits)) /
+				((__u64)curr->bytes_queued + curr->avg_rate);
+	
+		__u32 max2 = (256 * ((__u64)curr->credits +
+				curr->credit_in - curr->credit_out)) /
+				((__u64)curr->bytes_queued + 2*curr->avg_rate);
+
+		__u32 maxcost = max(0, min((max1), (max2)));
+
+		if (maxcost > currcost_limit) {
+			currcost = currcost_limit;
+			currcost_limit = maxcost;
+			best = curr;
+		}
+	}
+
+	best->credits -= currcost;
+
+	ret = __skb_dequeue(&(best->queue));
+	spin_unlock(&(q->lock));
+
+	if (likely(ret != NULL)) {
+		sch->qstats.backlog -= ret->len;
+		sch->q.qlen--;
+	}
+
+	return ret;
+}
+
+
+static void activate_conn(struct cor_sched_data *q, struct conn_qdisc_info *qi)
+{
+	if (unlikely(qi->qdisc_active == 0)) {
+		spin_lock(&(q->lock));
+
+		qi->le.next = (struct conn_qdisc_info*) &(q->cql);
+		qi->le.prev = q->cql.last;
+		q->cql.last = qi;
+
+		if (unlikely(q->cql.first))
+			q->cql.first = q->cql.last;
+
+		spin_unlock(&(q->lock));
+	}
+}
+
+static int cor_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+	struct cor_sched_data *q = qdisc_priv(sch);
+	struct conn_qdisc_info *qi;
+
+	BUG_TRAP(skb_pstate(&skb)->conn->targettype != TARGET_OUT);
+
+	qi = &(skb_pstate(&skb)->conn->target.out.qi);
+
+	spin_lock(&(qi->lock));
+
+	__skb_queue_tail(&(qi->queue), skb);
+	activate_conn(q, qi);
+
+	spin_unlock(&(qi->lock));
+
+	sch->bstats.bytes += skb->len;
+	sch->bstats.packets++;
+	sch->q.qlen++;
+	
+	return NET_XMIT_SUCCESS;
+}
+
+static int cor_requeue(struct sk_buff *skb, struct Qdisc *sch)
+{
+	struct cor_sched_data *q = qdisc_priv(sch);
+	struct conn_qdisc_info *qi;
+
+	BUG_TRAP(skb_pstate(&skb)->conn->targettype != TARGET_OUT);
+
+	qi = &(skb_pstate(&skb)->conn->target.out.qi);
+
+	spin_lock(&(qi->lock));
+
+	__skb_queue_head(&(qi->queue), skb);
+	activate_conn(q, qi);
+
+	spin_unlock(&(qi->lock));
+
+	sch->qstats.requeues++;
+	sch->q.qlen++;
+
+	return NET_XMIT_SUCCESS;
+}
+
+static void init_scheddata(struct cor_sched_data *q)
+{
+	#warning TODO
+}
+
+static void cor_reset(struct Qdisc *sch)
+{
+	#warning TODO terminate connections, free all packets and delete all connection stats
+}
+
+static void cor_destroy(struct Qdisc *sch)
+{
+	//free ressources
+}
+
+static int cor_change(struct Qdisc *sch, struct rtattr *opt)
+{
+	struct cor_qdisc_opts *ctl = RTA_DATA(opt);
+	if (RTA_PAYLOAD(opt) < sizeof(*ctl))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int cor_init(struct Qdisc *sch, struct rtattr *opt)
+{
+	struct cor_sched_data *q = qdisc_priv(sch);
+	init_scheddata(q);
+	spin_lock_init( &(q->lock) );
+	return cor_change(sch, opt);
+}
+
+static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
+{
+	/*struct red_sched_data *q = qdisc_priv(sch);
+	struct tc_red_xstats st = {
+		.early	= q->stats.prob_drop + q->stats.forced_drop,
+		.pdrop	= q->stats.pdrop,
+		.other	= q->stats.other,
+		.marked	= q->stats.prob_mark + q->stats.forced_mark,
+	};
+
+	return gnet_stats_copy_app(d, &st, sizeof(st));*/
+	return 0;
+}
+
+static struct Qdisc_ops cor_qdisc_ops = {
+	.id		=	"cor",
+	.priv_size	=	sizeof(struct cor_sched_data),
+	.cl_ops		=	0,
+	.enqueue	=	cor_enqueue,
+	.dequeue	=	cor_dequeue,
+	.requeue	=	cor_requeue,
+	.drop		=	0,
+	.init		=	cor_init,
+	.reset		=	cor_reset,
+	.destroy	=	cor_destroy,
+	.change		=	cor_change,
+	.dump_stats	=	red_dump_stats,
+	.owner		=	THIS_MODULE,
+};
+
+static int __init cor_module_init(void)
+{
+	return register_qdisc(&cor_qdisc_ops);
+}
+
+static void __exit cor_module_exit(void)
+{
+	unregister_qdisc(&cor_qdisc_ops);
+}
+
+module_init(cor_module_init)
+module_exit(cor_module_exit)
+
+MODULE_LICENSE("GPL");
diff -u -r -N ./net/cor/rcv.c ./net/cor/rcv.c
--- ./net/cor/rcv.c	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/rcv.c	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1,283 @@
+#ifndef _KERNEL_
+	#define _KERNEL_
+#endif
+
+#ifndef MODULE
+	#define MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/in.h>
+
+
+#include "cor.h"
+#include "settings.h"
+
+
+struct packet_queue{
+	/*
+	 *  This is a single linked list!!!!!
+	 */
+	struct sk_buff *head;
+	struct sk_buff *tail;
+
+	spinlock_t lock;
+
+	wait_queue_head_t readers;
+};
+
+struct packet_queue rcv_queue;
+
+struct htable pid_table;
+
+atomic_t ooo_packets = ATOMIC_INIT(0);
+
+#warning todo right side of conn?
+int put_packet_id_def(struct sk_buff *skb, struct conn *conn, int spaceleft)
+{
+}
+
+
+static int is_next_packet(struct sk_buff *skb)
+{
+	struct skb_procstate *ps = skb_pstate(&skb);
+
+	BUG_TRAP(ps->conn == 0);
+	BUG_TRAP(ps->conn->sourcetype != SOURCE_IN);
+	
+	return ps->conn->source.in.next_packet_id == ps->funcstate.in;
+}
+
+static void local_delivery(struct sk_buff *skb)
+{
+	#warning todo
+	#warning multiple chained skbs
+/*	struct skb_procstate *ps=skb_pstate(&(skb));
+	struct cor_sock *sk=&(ps->funcstate.target.sock);
+	#error
+	__skb_queue_tail(&sk->sk_receive_queue, skb);
+	sk->sk_data_ready(sk, skb->length);*/
+}
+
+static void resize(struct sk_buff *skb)
+{
+	#warning multiple chained skbs?
+	#warning call send_packet afterwards
+	#warning race
+	long iflags;
+
+	struct conn *conn = skb_pstate(&skb)->conn;
+	struct resize_buf *rbuf = &(conn->target.out.rb);
+	int targetmss = mss(conn->target.out.nb);
+
+	spin_lock_irqsave(&(rbuf->lock), iflags);
+
+	#warning packet_id???
+	#warning skb->len == data to pull?
+	if (rbuf->skb_first == 0 && skb->len == targetmss) {
+		send_packet(skb);
+		goto out;
+	}
+	if (rbuf->skb_first == 0){
+		rbuf->skb_first = skb;
+		rbuf->skb_last = skb;
+	} else {
+		rbuf->skb_last->next = skb;
+		rbuf->skb_last = skb;
+	}
+
+	rbuf->totalsize += skb->len;
+
+	while (rbuf->totalsize >= targetmss) {
+		struct sk_buff *newskb = create_packet(conn, targetmss,
+				GFP_ATOMIC);
+		int totalcopy;
+		for (totalcopy = 0; totalcopy < targetmss; ) {
+			int copy = min(skb->len, targetmss - totalcopy);
+
+			#warning error
+			char *src = skb_pull(skb, copy);
+			char *dest = skb_put(newskb, copy);
+
+			memcpy(dest, src, copy);
+
+			totalcopy += copy;
+			#warning kfree_skb
+		}
+
+		send_packet(newskb);
+		rbuf->totalsize -= targetmss;
+	}
+out:
+	spin_unlock_irqrestore(&(rbuf->lock), iflags);
+}
+
+
+static void routing(struct sk_buff *skb)
+{
+	struct skb_procstate *ps = skb_pstate(&(skb));
+
+	if (ps->conn->targettype == TARGET_SOCK)
+		local_delivery(skb);
+	else if (ps->conn->targettype == TARGET_OUT)
+		resize(skb);
+	else
+		BUG();
+	send_ack(ps->conn->source.in.nb, ps->funcstate.in->packet_id);
+}
+
+static void reordering(struct sk_buff *skb)
+{
+	#warning global ooo packets counter
+	long iflags;
+
+	struct skb_procstate *ps = skb_pstate(&(skb));
+	struct sk_buff *next_packets = 0;
+
+	BUG_TRAP(0 != skb->next);
+	BUG_TRAP(0 != skb->prev);
+	BUG_TRAP(SOURCE_IN != ps->conn->sourcetype);
+
+	spin_lock_irqsave( &(ps->conn->source.in.reorder_lock), iflags );
+	if (!is_next_packet(skb)) {
+		if (unlikely(MAX_TOTAL_OOO_PER_CONN >=
+				ps->conn->source.in.ooo_packets)) {
+			kfree_skb(skb);
+			goto out;
+		}
+
+		ps->conn->source.in.ooo_packets++;
+		ps->funcstate.in->skb = skb;
+		goto out;
+	}
+
+
+	struct packet_id_in *curr = ps->conn->source.in.next_packet_id;
+	struct packet_id_in *old;
+	while (0 != curr && 0 != curr->skb) {
+		ps->conn->source.in.ooo_packets--;
+		if (0 != skb->next)
+			skb->next = curr->skb;
+		curr->skb->prev = skb->prev;
+		skb->prev = curr->skb;
+		curr->skb->next = skb;
+
+		old = curr;
+		curr = curr->next;
+		kfree(old);
+	}
+
+	ps->conn->source.in.next_packet_id = curr;
+
+	routing(skb);
+out:
+	spin_unlock_irqrestore( &(ps->conn->source.in.reorder_lock), iflags );
+}
+
+static void announce_packet(struct sk_buff *skb)
+{
+	#warning todo
+}
+
+static void rcv(struct sk_buff *skb)
+{
+	struct skb_procstate *ps = skb_pstate(&skb);
+	__u32 *pid = (__u32 *)skb_pull(skb, 4);
+	struct packet_id_in *pid_in;
+
+	if (0 == pid)
+		goto drop;
+
+	if (unlikely(0 == *pid)) {
+		announce_packet(skb);
+		return;
+	}
+	
+	pid_in = get_packet_id(*pid);
+
+	ps->conn = pid_in->conn;
+#warning	ps->funcstate.in = pid;
+
+	if (unlikely(0 == ps->conn))
+		goto drop;
+
+	if (unlikely(TARGET_KERNEL == ps->conn->targettype)) {
+#warning at the moment kernel packets are not reordered properly
+		kernel_packet(skb);
+		return;
+	}
+
+	reordering(skb);
+	return;
+drop:
+	kfree_skb(skb);
+}
+
+static void rcv_thread(void)
+{
+	while (1) {
+		struct sk_buff *skb = 0;
+
+		unsigned long iflags;
+		spin_lock_irqsave( &(rcv_queue.lock), iflags );
+
+		if (0 == rcv_queue.head) {
+			spin_unlock_irqrestore( &(rcv_queue.lock), iflags );
+			wait_event_interruptible(rcv_queue.readers,
+					rcv_queue.head != 0);
+			continue;
+		}
+
+		skb = rcv_queue.head;
+
+		rcv_queue.head = rcv_queue.head->next;
+		if (0 == rcv_queue.head)
+			rcv_queue.tail = 0;
+
+		spin_unlock_irqrestore( &(rcv_queue.lock), iflags );
+
+		rcv(skb);
+	}
+}
+
+
+static int queue_rcv_processing(struct sk_buff *skb, struct net_device *dev,
+		struct packet_type *pt)
+{
+	unsigned long iflags;
+
+	BUG_TRAP(skb->next != 0);
+
+	spin_lock_irqsave( &(rcv_queue.lock), iflags );
+
+	if (0 == rcv_queue.tail)
+		rcv_queue.head = rcv_queue.tail = skb;
+	else
+		rcv_queue.tail->next = skb;
+
+	spin_unlock_irqrestore( &(rcv_queue.lock), iflags );
+
+	wake_up_interruptible(&(rcv_queue.readers));
+
+	return skb->len;
+}
+
+
+static struct packet_type ptype_cor = {
+	.type = __constant_htons(ETH_P_COR),
+	.dev = 0,
+	.func = queue_rcv_processing
+};
+
+int init_module(void)
+{
+	spin_lock_init( &(rcv_queue.lock) );
+	htable_init(&pid_table);
+	dev_add_pack(&ptype_cor);
+	return 0;
+}
+
+MODULE_LICENSE("GPL");
diff -u -r -N ./net/cor/settings.h ./net/cor/settings.h
--- ./net/cor/settings.h	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/settings.h	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1,4 @@
+#define MAX_TOTAL_OOO_PACKETS 100
+#define MAX_TOTAL_OOO_PER_CONN 10
+#define PACKET_IDS_ON_CONNECT 32
+
diff -u -r -N ./net/cor/snd.c ./net/cor/snd.c
--- ./net/cor/snd.c	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/snd.c	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1,265 @@
+#include <linux/gfp.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+
+#include "cor.h"
+#include "settings.h"
+
+struct htable retransmits;
+
+static inline int retransmit_keyoffset()
+{
+	struct sk_buff tmp;
+	struct skb_procstate tmp2;
+
+	return ((char *)(&(tmp.cb)) - (char *)(&tmp)) +
+			((char *)(&(tmp2.funcstate.retransmit_queue.sent_pid)) -
+			(char *)(&tmp2));
+}
+
+
+static int clear_retransmit(__u32 packet_id)
+{
+	struct sk_buff *ret;
+
+	struct skb_procstate *ps;
+
+	search_htab(&retransmits, packet_id, retransmit_keyoffset(),
+			(struct htab_entry **)&ret);
+
+	if (ret == 0)
+		return 1;
+
+	ps = skb_pstate(&(ret));
+	dec_connrefs(ps->conn);
+	kfree_skb(ret);
+		
+	return 0;
+}
+
+static void send_retransmit(struct sk_buff *skb)
+{
+	struct skb_procstate *ps = skb_pstate(&(skb));
+	struct neighbor *nb = ps->conn->target.out.nb;
+
+	nb->first_retransmit = ps->funcstate.retransmit_queue.next;
+	nb->first_retransmit->prev = 0;
+	ps->funcstate.retransmit_queue.next = 0;
+	ps->funcstate.retransmit_queue.prev = nb->last_retransmit;
+	nb->last_retransmit = skb;
+
+	ps->funcstate.retransmit_queue.timeout = jiffies + nb->latency;
+}
+
+static void retransmit_timerfunc(unsigned long arg)
+{
+	unsigned long iflags;
+
+	struct neighbor *nb = (struct neighbor *) arg;
+	struct sk_buff *skb;
+	struct skb_procstate *ps = 0;
+	__u32 timeout;
+
+	spin_lock_irqsave( &(nb->retrans_lock), iflags );
+
+	skb = nb->first_retransmit;
+
+	if (0 == skb)
+		goto out;
+
+	ps = skb_pstate(&(skb));
+	timeout = ps->funcstate.retransmit_queue.timeout;
+
+	if (time_after_eq(timeout, jiffies))
+		send_retransmit(skb);
+
+	mod_timer(&(nb->retrans_timer), timeout);
+
+out:
+	spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
+}
+
+
+static void sched_retransmit(struct sk_buff *skb)
+{
+	unsigned long iflags;
+
+	struct sk_buff *skb2 = skb_clone(skb, __GFP_DMA | GFP_KERNEL);
+	struct skb_procstate *ps = skb_pstate(&(skb2));
+	__u32 packet_id = ps->funcstate.retransmit_queue.sent_pid;
+	struct neighbor *nb = ps->conn->target.out.nb;
+
+	int ret = search_htab(&retransmits, packet_id, retransmit_keyoffset(),
+			(struct htab_entry **)&skb2);
+	BUG_TRAP(1 == ret);
+
+	spin_lock_irqsave( &(nb->retrans_lock), iflags );
+
+	ps->funcstate.retransmit_queue.next = 0;
+	ps->funcstate.retransmit_queue.prev = nb->last_retransmit;
+	nb->last_retransmit = skb2;
+	if (unlikely(0 == nb->first_retransmit)) {
+		nb->first_retransmit = skb;
+		mod_timer(&(nb->retrans_timer),
+				ps->funcstate.retransmit_queue.timeout);
+	}
+
+	spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
+}
+
+static void pop_pid(struct conn *conn, __u32 *packet_id)
+{
+	__u32 *packet_id_ptr;
+
+	struct packet_id_out *pid_out = conn->target.out.next_pid;
+
+	if (0 == pid_out) {
+		*packet_id = 0;
+		return;
+	}
+
+	BUG_TRAP(pid_out->num_ids == 0);
+
+	packet_id_ptr = (__u32 *)
+				(((char *) pid_out) +
+				((sizeof(struct packet_id_out) + 3) / 4) * 4);
+	packet_id_ptr += pid_out->offset;
+	*packet_id = *packet_id_ptr;
+
+	pid_out->offset++;
+	pid_out->num_ids--;
+
+	if (unlikely(0 == pid_out->num_ids)) {
+		conn->target.out.next_pid = pid_out->next;
+		if (unlikely(conn->target.out.last_pid == pid_out)) {
+			BUG_TRAP(pid_out->next != 0);
+			conn->target.out.last_pid = 0;
+		}
+		#warning todo free pid_out
+	}
+}
+
+static void check_send_packet_id(struct conn *target,
+		struct packet_id_out *pid_out, int *packet_id_sent)
+{
+	if (unlikely(0 == pid_out->next && 1 == pid_out->num_ids &&
+			0 == packet_id_sent)) {
+		__u32 packet_id;
+		pop_pid(target, &packet_id);
+		#warning todo send packet id definition
+	}
+}
+
+static void next_pid(struct conn *conn, __u32 *packet_id, int *packet_id_sent)
+{
+	unsigned long iflags;
+
+	struct packet_id_out *pid_out;
+
+	*packet_id = 0;
+
+	spin_lock_irqsave( &(conn->target.out.pid_lock), iflags );
+
+	*packet_id_sent = conn->target.out.packet_id_sent;
+	pid_out = conn->target.out.next_pid;
+
+	if (0 == pid_out)
+		goto out;
+
+	check_send_packet_id(conn, pid_out, packet_id_sent);
+
+	pop_pid(conn, packet_id);
+out:
+	spin_unlock_irqrestore( &(conn->target.out.pid_lock), iflags );
+
+	if (unlikely(*packet_id == 0 && *packet_id_sent == 0)) {
+		#warning todo log error + reset connection
+		/* (in a way that doesn't crash the caller) */
+	}
+}
+
+
+
+struct sk_buff* create_packet(struct conn *target, int size, int alloc_flags)
+{
+	struct skb *ret;
+
+	struct neighbor *nb = target->target.out.nb;
+	struct net_device *dev = nb->dev;
+
+	__u32 packet_id = 0;
+	int packet_id_sent;
+
+	__u32 *dest;
+
+	#warning todo
+	/*if(!(target->state & TARGET_STATEMASK_READY))
+		return 0;*/
+
+	next_pid(target, &packet_id, &packet_id_sent);
+
+	if (0 == packet_id) {
+		/* ??? */
+	}
+
+
+	/*ret = alloc_skb(size + dev->hard_header_len, alloc_flags);
+	if(dev->hard_header){
+		if(unlikely(dev->hard_header(ret, dev, ETH_P_COR, nb->mac,
+				dev->dev_addr, ret->len) < 0)){
+
+			#warning error
+		}
+	}*/
+
+	dest = (__u32 *) skb_put(ret, 4);
+	BUG_TRAP(0 == dest);
+	*dest = htonl(packet_id);
+
+	return ret;
+}
+
+void send_packet(struct sk_buff *skb)
+{
+	struct skb_procstate *ps = skb_pstate(&skb);
+	BUG_TRAP(TARGET_OUT != ps->conn->targettype);
+
+	sched_retransmit(skb);
+	#warning xmit
+}
+
+struct conn *ack_received(struct neighbor *nb, __u32 packet_id, int nack)
+{
+	unsigned long iflags;
+
+	struct sk_buff *skb = 0;
+	struct skb_procstate *ps = 0;
+
+	int ret = search_htab(&retransmits, packet_id, retransmit_keyoffset(),
+			(struct htab_entry **)&skb);
+
+	if (0 == ret)
+		return 0;
+
+	ps = skb_pstate(&(skb));
+	if (nb != ps->conn->target.out.nb) {
+		#warning todo bogus packet received
+	}
+
+	spin_lock_irqsave( &(nb->retrans_lock), iflags );
+
+	if (unlikely(nb->first_retransmit == skb)) {
+		if (unlikely(nb->last_retransmit == skb)) {
+			nb->first_retransmit = nb->last_retransmit = 0;
+		} else {
+			nb->first_retransmit = skb->next;
+			mod_timer(&(nb->retrans_timer), jiffies + nb->latency);
+		}
+	}
+
+	spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
+
+	kfree_skb(skb);
+}
+
+MODULE_LICENSE("GPL");
diff -u -r -N ./net/cor/sock.c ./net/cor/sock.c
--- ./net/cor/sock.c	1970-01-01 01:00:00.000000000 +0100
+++ ./net/cor/sock.c	2007-12-09 10:47:35.000000000 +0100
@@ -0,0 +1,138 @@
+#include <net/sock.h>
+#include <linux/net.h>
+
+#include "cor.h"
+
+int cor_socket_release(struct socket *sock)
+{
+}
+
+int cor_socket_bind(struct socket *sock, struct sockaddr *myaddr,
+		int sockaddr_len)
+{
+}
+
+int cor_socket_connect(struct socket *sock, struct sockaddr *vaddr,
+		int sockaddr_len, int flags)
+{	
+}
+
+int cor_socket_accept(struct socket *sock, struct socket *newsock, int flags)
+{
+}
+
+int cor_socket_listen(struct socket *sock, int len)
+{
+}
+
+int cor_socket_shutdown(struct socket *sock, int flags)
+{
+}
+
+int cor_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+}
+
+int cor_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
+		size_t total_len)
+{
+	#warning TODO
+	int copy=0;
+	int err=0;
+
+	struct conn *conn = sock->sk;
+	
+	/*long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);*/
+
+	while (1) {
+		//struct sk_buff *skb = sk->sk_write_queue.next;
+		
+		//if(skb)
+		//	goto copy;
+
+		//if((err = sk_stream_wait_memory(sk, &timeo)) != 0)
+		//	goto out;
+
+		//skb=create_new_packet(target);
+		//if(skb == 0)
+//copy:
+	}
+
+//out:
+	//sk->sk_wmem_queued+=copy;
+	if (copy)
+		return copy;
+	return err;
+}
+
+int cor_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
+		size_t total_len, int flags)
+{
+	int nonblock = flags & MSG_DONTWAIT;
+	struct conn *sk = sock->sk;
+	size_t copied = 0;
+	/*while(copied < total_len){
+		if (skb != 0) {
+			#warning lock?
+			struct sk_buff *skb = __skb_dequeue(&(best->queue));
+			#warning copied???
+			#warning ???
+			skb_copy_datagram_iovec(skb, 0, m->msg_iov, skb->len);
+		} else if(nonblock || (copied > 0)) {
+			break;
+		} else {
+			wait_event_interruptible(rcv_queue.readers,
+					rcv_queue.head != 0);
+		}
+
+	}*/
+	return (copied != 0) ? copied : (-EAGAIN);
+}
+
+const struct proto_ops cor_proto_ops = {
+		//.family =
+		.owner = THIS_MODULE,
+		.release = cor_socket_release,
+		.bind = cor_socket_bind,
+		.connect = cor_socket_connect,
+		.accept = cor_socket_accept,
+		.listen = cor_socket_listen,
+		.shutdown = cor_socket_shutdown,
+		.ioctl = cor_ioctl,
+		.sendmsg = cor_sendmsg,
+		.recvmsg = cor_recvmsg
+};
+
+
+int cor_createsock(struct socket *sock, int protocol)
+{
+	struct conn *conn_rcv;
+	struct conn *conn_snd;
+
+	#warning todo
+	//conn_rcv = sk_alloc(PF_INET, GFP_KERNEL, &cor_proto_ops, 1);
+	if (conn_rcv == NULL)
+		goto out;
+
+	//conn_snd = sk_alloc(PF_INET, GFP_KERNEL, &cor_proto_ops, 1);
+	if (conn_snd == NULL)
+		goto out;
+
+	/*socket->ops = cor_proto_ops*/
+out:
+	
+	return 0;
+}
+
+
+const struct net_proto_family cor_net_proto_family = {
+//	.family=,
+	.create = cor_createsock,
+//	.authentication = 0,
+//	.encryption = 0,
+//	.encrypt_net = 0,
+	.owner=THIS_MODULE
+};
+
+MODULE_LICENSE("GPL");
+

