From b1cad22b94537eaf59954649e5ad938a753f6d4c Mon Sep 17 00:00:00 2001 From: Michael Blizek Date: Sun, 28 Feb 2010 12:19:56 +0100 Subject: [PATCH] ping reqs --- net/cor/cor.h | 34 ++++++++++++++++++----- net/cor/kpacket_gen.c | 72 +++++++++++++++++++++++++++++++++++++++++++++---- net/cor/kpacket_parse.c | 23 ++++++++++++++++ 3 files changed, 117 insertions(+), 12 deletions(-) diff --git a/net/cor/cor.h b/net/cor/cor.h index 02a929821c7..de1ac2b3108 100644 --- a/net/cor/cor.h +++ b/net/cor/cor.h @@ -64,13 +64,30 @@ struct cor_sockaddr { /* KP_PADDING[1] */ #define KP_PADDING 1 -/* KP_[N]ACK[1] sent_conn_id[4] seqno[4] +/* + * KP_PING[1] cookie[4] + * KP_PONG[1] cookie[4] respdelay[4] + * + * This is needed to find out whether the other node is reachable. After a new + * neighbor is seen, ping requests are sent and the neighbor is only reachable + * after a few pongs are received. These requests are also used to find out + * whether a neighber is gone. + * + * respdelay: + * The receiver of a ping may delay the sending of the pong e.g. to create + * bigger kernel packets. The respdelay is the time in microseconds the packet + * was delayed. + */ +#define KP_PING 2 +#define KP_PONG 3 + +/* KP_ACK[1] sent_conn_id[4] seqno[4] * * sent_conn_id means that this is *not* the conn_id we use if we sent something * through this conn, but the conn_id that the neighbor used to send us the * packet */ -#define KP_ACK 2 +#define KP_ACK 4 /* * KP_SPEED[1] conn_id[4] speedinfo[2] @@ -100,7 +117,7 @@ struct cor_sockaddr { * if buffer_state_value if > 91, you have to subtract 90 and make the * resulting buffer_state negative */ -#define KP_SPEED 3 +#define KP_SPEED 5 /* NOTE on connection ids: * connection ids we send are used for the receive channel @@ -111,7 +128,7 @@ struct cor_sockaddr { * incoming connection * KP_CONNECT[1] conn_id[4] */ -#define KP_CONNECT 4 +#define KP_CONNECT 6 /* * incoming connection successful, @@ -119,16 +136,16 @@ struct cor_sockaddr { * the second conn_id is generated by us and used for the other direction * KP_CONNECT_SUCCESS[1] conn_id[4] conn_id[4] */ -#define KP_CONNECT_SUCCESS 5 +#define KP_CONNECT_SUCCESS 7 /* KP_CONN_DATA[1] conn_id[4] seqno[4] length[2] data[length] */ -#define KP_CONN_DATA 6 +#define KP_CONN_DATA 8 /* * { KP_RESET_CONN[1] conn_id[4] } * We send this, if there is an established connection we want to close. */ -#define KP_RESET_CONN 7 +#define KP_RESET_CONN 9 /* @@ -547,6 +564,9 @@ extern struct control_msg_out *alloc_control_msg(void); extern void free_control_msg(struct control_msg_out *cm); +extern void send_pong(struct control_msg_out *cm, struct neighbor *nb, + __u32 cookie); + extern void send_reset_conn(struct control_msg_out *cm, struct neighbor *nb, __u32 conn_id); diff --git a/net/cor/kpacket_gen.c b/net/cor/kpacket_gen.c index 6015459a194..6418c56a050 100644 --- a/net/cor/kpacket_gen.c +++ b/net/cor/kpacket_gen.c @@ -23,11 +23,13 @@ #include "cor.h" /* not sent over the network - internal meaning only */ -#define MSGTYPE_ACK 1 -#define MSGTYPE_CONNECT 2 -#define MSGTYPE_CONNECT_SUCCESS 3 -#define MSGTYPE_RESET_CONN 4 -#define MSGTYPE_CONNDATA 5 +#define MSGTYPE_PING 1 +#define MSGTYPE_PONG 2 +#define MSGTYPE_ACK 3 +#define MSGTYPE_CONNECT 4 +#define MSGTYPE_CONNECT_SUCCESS 5 +#define MSGTYPE_RESET_CONN 6 +#define MSGTYPE_CONNDATA 7 /* * lh must be first @@ -41,6 +43,15 @@ struct control_msg_out{ __u8 type; union{ struct{ + __u32 cookie; + }ping; + + struct{ + __u32 cookie; + unsigned long time_enqueued; /* jiffies */ + }pong; + + struct{ __u32 conn_id; __u32 seqno; }ack; @@ -100,6 +111,42 @@ static int add_ack(struct sk_buff *skb, struct control_msg_out *cm, return 9; } +static int add_ping(struct sk_buff *skb, struct control_msg_out *cm, + int spaceleft) +{ + char *dst; + + if (spaceleft < 5) + return 0; + + dst = skb_put(skb, 5); + BUG_ON(0 == dst); + + dst[0] = KP_PING; + put_u32(dst + 1, cm->msg.ping.cookie, 0); + + return 5; +} + +static int add_pong(struct sk_buff *skb, struct control_msg_out *cm, + int spaceleft) +{ + char *dst; + + if (spaceleft < 9) + return 0; + + dst = skb_put(skb, 9); + BUG_ON(0 == dst); + + dst[0] = KP_ACK; + put_u32(dst + 1, cm->msg.pong.cookie, 0); + put_u32(dst + 5, jiffies_to_msecs(jiffies - cm->msg.pong.time_enqueued, + 1); + + return 9; +} + static int add_connect(struct sk_buff *skb, struct control_msg_out *cm, int spaceleft) { @@ -201,6 +248,12 @@ static int add_message(struct sk_buff *skb, struct control_msg_out *cm, case MSGTYPE_ACK: rc = add_ack(skb, cm, spaceleft); break; + case MSGTYPE_PING: + rc = add_ping(skb, cm, spaceleft); + break; + case MSGTYPE_PONG: + rc = add_pong(skb, cm, spaceleft); + break; case MSGTYPE_CONNECT: rc = add_connect(skb, cm, spaceleft); break; @@ -355,6 +408,15 @@ static void add_control_msg(struct control_msg_out *msg, struct neighbor *nb) mutex_unlock(&(nb->cmsg_lock)); } +void send_pong(struct control_msg_out *cm, struct neighbor *nb, __u32 cookie) +{ + cm->type = MSGTYPE_PONG; + cm->msg.pong.cookie = cookie; + cm->msg.pong.time_enqueued = jiffies; + cm->length = 9; + add_control_msg(cm, nb); +} + void send_reset_conn(struct control_msg_out *cm, struct neighbor *nb, __u32 conn_id) { diff --git a/net/cor/kpacket_parse.c b/net/cor/kpacket_parse.c index 6e28a52e8b9..1a71432d609 100644 --- a/net/cor/kpacket_parse.c +++ b/net/cor/kpacket_parse.c @@ -194,6 +194,10 @@ static void kernel_packet2(struct neighbor *nb, struct sk_buff *skb, return; while (1) { + struct control_msg_out *cm_tmp; + __u32 cookie; + __u32 respdalay; + __u32 conn_id; __u32 seqno; @@ -210,6 +214,17 @@ static void kernel_packet2(struct neighbor *nb, struct sk_buff *skb, switch (code) { case KP_PADDING: break; + case KP_PING: + cookie = pull_u32(skb, 0); + cm_tmp = alloc_control_msg(); + if (likely(cm != 0)) { + send_pong(cm, nb, cookie); + } + break; + case KP_PONG: + cookie = pull_u32(skb, 0); + respdelay = pull_u32(skb, 1); + break; case KP_ACK: conn_id = pull_u32(skb, 1); seqno = pull_u32(skb, 1); @@ -266,6 +281,14 @@ void kernel_packet(struct neighbor *nb, struct sk_buff *skb, __u32 seqno) switch (code) { case KP_PADDING: break; + case KP_PING: + if (cor_pull_skb(skb2, 4) == 0) + goto discard; + break; + case KP_PONG: + if (cor_pull_skb(skb2, 8) == 0) + goto discard; + break; case KP_ACK: if (cor_pull_skb(skb2, 8) == 0) goto discard; -- 2.11.4.GIT