#include #include #include #include #include #include #include #include #include #ifdef CONFIG_KMOD #include #endif extern void tcp_cs_send_ack(struct sk_buff *skb, __u32 seq, __u32 ack, __u16 window); extern struct sock *tcp_cs_lookup(struct tcphdr *th, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif); extern void tcp_cs_measure_mss(struct sock *sk, struct sk_buff *skb); void ip_cs_bind_masq_svc(struct ip_masq *ms, struct ip_vs_service *svc) { ms->svc=svc; printk("*****bind service\n"); } struct ip_masq *ip_cs_create_new(struct ip_vs_service *svc, struct iphdr *iph) { struct ip_masq *ms =NULL; __u32 saddr; __u16 sport; const __u16 *portp; portp = (__u16 *)&(((char *)iph)[iph->ihl*4]); saddr=0; sport=0; read_lock(&__ip_vs_lock); /* * Create a masquerading entry. */ ms = ip_masq_new_vs(iph->protocol, iph->daddr, portp[1], saddr, sport, iph->saddr, portp[0], 0); if (ms == NULL) { IP_VS_ERR("Schedule: ip_masq_new_vs failed\n"); read_unlock(&__ip_vs_lock); return ms; } ip_cs_bind_masq_svc(ms, svc); read_unlock(&__ip_vs_lock); return ms; } int ip_cs_schedule(struct ip_masq *ms,struct sk_buff *skb) { register struct list_head *p, *q; struct ip_vs_dest *dest; int cs_len; __u32 addr; char cs_data[5000]; unsigned char *payload; struct iphdr *iph1=skb->nh.iph; struct ip_vs_service *service=ms->svc; payload=skb->data+iph1->ihl*4+skb->h.th->doff*4; cs_len=skb->len-(iph1->ihl*4+skb->h.th->doff*4); if(cs_len>0){ memset(cs_data,0,cs_len+1); memcpy(cs_data,payload,cs_len); printk("======DATA=%s\n",cs_data); printk("======POINTER skb->head=%lu skb->end=%lu skb->data=%lu skb->tail=%lu payload_len=%d\n",skb->head,skb->end,skb-> data,skb->tail,cs_len); } read_lock(&__ip_vs_lock); if(cs_data[5]=='~') addr=0x80c6c0c1; else addr=0x80c6c0c6; /*dest = service->scheduler->schedule(service);*/ p = (struct list_head *)service->sched_data; p = p->next; q = p; do { if (q == &service->destinations) { q = q->next; continue; } dest = list_entry(q, struct ip_vs_dest, n_list); if (ntohl(dest->addr)==addr) /* HIT */ goto out; q = q->next; } while (q != p); dest = NULL; out: service->sched_data = q; if (dest == NULL) { printk("*********Schedule: no dest found.\n"); read_unlock(&__ip_vs_lock); return -1; } ms->saddr = dest->addr; ms->sport = dest->port; printk("*********bind dest dest->addr=%08X dest->port=%04X \n",ntohl(dest->addr),ntohl(dest->port)); ip_vs_bind_masq(ms, dest); atomic_inc(&dest->inactconns); read_unlock(&__ip_vs_lock); return 0; } void ip_cs_err_handle(){ printk("********ip_cs_error\n"); } int ip_cs_content_complete_check(struct sk_buff *skb) { struct iphdr *iph=skb->nh.iph; if((skb->len-(iph->ihl*4+skb->h.th->doff*4))>0) return 1; else return 0; } int ip_cs_syn_in(struct sk_buff *skb, struct ip_masq *ms) { struct sk_buff *skb1; struct iphdr *iph1= skb->nh.iph; union ip_masq_tphdr h1; h1.raw = (char*) iph1 + iph1->ihl * 4; ms->cs_flags=IP_CS_F_CONN_CLIENT; ms->seq=ntohl(h1.th->seq); skb1=skb_copy(skb,GFP_ATOMIC); if(skb1==NULL){ ip_cs_err_handle(); return -1; } skb_queue_head(&ip_cs_req_queue,skb1); printk("\n*********SYN_REQUEST-- Sip=%08X Dip=%08X Seq=%08lu len=%4d\n", ntohl(iph1->saddr),ntohl(iph1->daddr), ntohl(h1.th->seq),skb->len); return 0; } int ip_cs_ack_in_client(struct sk_buff *skb, struct ip_masq *ms) { struct sk_buff *skb1; struct iphdr *iph1= skb->nh.iph; union ip_masq_tphdr h1; __u32 seq; h1.raw = (char*) iph1 + iph1->ihl * 4; if((h1.th->ack)&&(ms->cs_seq==0)){ seq=ntohl(h1.th->ack_seq); ms->cs_seq=seq-1; return 0; } skb1=skb_copy(skb,GFP_ATOMIC); if(skb1==NULL) return -1; skb_queue_head(&ip_cs_req_queue,skb1); printk("********ACK_BACK_FROM_CLIENT Sip=%08X Dip=%08X seq=%08lu ack_seq=%8lu len=%4d\n",ntohl(iph1->saddr),ntohl(iph1->daddr),ntohl(h1.th->seq),ntohl(h1.th->ack_seq),skb->len); if(ip_cs_content_complete_check(skb)==0) return 0; else return 1; } struct sk_buff * ip_cs_prepare_skb_server(struct sk_buff *skb,struct ip_masq *ms) { struct sk_buff *skb1; ms->cs_flags=IP_CS_F_CONN_SERVER; kfree_skb(skb); skb1 = skb_dequeue_tail(&ip_cs_req_queue); return skb1; } struct sk_buff * ip_cs_prepare_skb_cs(struct sk_buff *skb,struct ip_masq *ms) { struct sk_buff *skb1; kfree_skb(skb); skb1 = skb_dequeue_tail(&ip_cs_req_queue); return skb1; } void ip_cs_fix_client_seq(struct sk_buff *skb,struct ip_masq *ms) { struct iphdr *iph1= skb->nh.iph; union ip_masq_tphdr h1; __u32 seq; h1.raw = (char*) iph1 + iph1->ihl * 4; seq=ntohl(h1.th->ack_seq); if(ms->cs_seq>ms->svr_seq) h1.th->ack_seq=htonl(seq-(ms->cs_seq-ms->svr_seq)); else h1.th->ack_seq=htonl(seq+(ms->svr_seq-ms->cs_seq)); } void ip_cs_fix_server_seq(struct sk_buff *skb,struct ip_masq *ms) { struct iphdr *iph1= skb->nh.iph; union ip_masq_tphdr h1; __u32 seq; h1.raw = (char*) iph1 + iph1->ihl * 4; seq=ntohl(h1.th->seq); if (ms->cs_seq>ms->svr_seq) h1.th->seq=htonl(seq+(ms->cs_seq-ms->svr_seq)); else h1.th->seq=htonl(seq-(ms->svr_seq-ms->cs_seq)); } void ip_cs_ack_in_server(struct sk_buff *skb, struct ip_masq *ms) { struct iphdr *iph1= skb->nh.iph; union ip_masq_tphdr h1; h1.raw = (char*) iph1 + iph1->ihl * 4; printk("ssssssss ACK FROM SERVER sip=%08X dip=%08X seq=%08lu ack_seq=%08lu\n",ntohl(iph1->saddr),ntohl(iph1->daddr),ntohl(h1.th->seq),ntohl(h1.th->ack_seq)); if((h1.th->syn)&&(h1.th->ack)&&(ms->svr_seq==0)){ ms->svr_seq=ntohl(h1.th->seq); printk("ssssssssSYNACK FROM SERVER\n"); } } int ip_cs_send_ack_to_client(struct sk_buff *skb) { struct tcphdr *th; struct sock *sk; struct tcp_opt *tp; /*__u32 seq,ack; __u16 window;*/ unsigned short len; skb->h.raw=skb->nh.raw+skb->nh.iph->ihl*4; th=skb->h.th; __skb_pull(skb, skb->h.raw - skb->data); len = skb->len; TCP_SKB_CB(skb)->seq = ntohl(th->seq); TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + len - th->doff*4); TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); /*seq=ntohl(th->ack_seq); ack=ntohl(th->seq)+len; window=ntohl(th->window); tcp_cs_send_ack(skb,seq,ack,window);*/ sk = tcp_cs_lookup(th, skb->nh.iph->saddr, th->source, skb->nh.iph->daddr, th->dest, skb->dev->ifindex); printk("TTTTTT IP_CS_SEND sip=%08X dip=%08X sport=%04X dport=%04X ifindex=%d seq=%08lu ack_seq=%08lu len=%d\n",ntohl(skb->nh.iph->saddr),ntohl(skb->nh.iph->daddr),ntohs(th->source),ntohs(th->dest),skb->dev->ifindex,ntohl(th->seq),ntohl(th->ack_seq),skb->len); if(!sk){ printk("NNNNNN NO socket\n"); return -1; } tp = &(sk->tp_pinfo.af_tcp); __skb_pull(skb,th->doff*4); tcp_cs_measure_mss(sk, skb); tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; tcp_send_ack(sk); return 1; }