AGW(LVS)后端RS全挂代码优化

来源:互联网 发布:c语言大于等于符号 编辑:程序博客网 时间:2024/05/23 14:38

        转载请注明出处:http://blog.csdn.net/hliyuxin/article/details/43375327

        如果LVS上一个VIP下挂的RS全都不可用, 原LVS采用的方式是DROP掉访问该VIP的包。出现这种情况,我们需要最短时间反馈给监控该VIP不可用,降低应用的不可用时长。 我们采用的改进方法是当该VIP的RS都不可用时,第一个syn包直接回复RST包,这个结果类似访问一个IP不存在的PORT。

设计方法是svc结构体增加weight变量,代表下挂rs的weight的和,当rs都不可用时svc->weight = 0.处理逻辑:


    

RST包构造代码(DPDK)

        unsigned short tmpport;
        uint32_t tmpAddr;


        struct ipv4_hdr *iph = ipv4_hdr(mbuf);
        struct tcp_hdr *th = tcp_v4_hdr(iph);
        uint32_t tcphoff = ipv4_hdrlen(iph);


        int needs_ack = 0;
        uint32_t tcplen = rte_cpu_to_be_16(iph->total_length) - tcphoff;


        /* reset seq ack_seq */
        if(unlikely(th->tcp_flags & TCP_FLAG_ACK)) {
                th->sent_seq = th->recv_ack;
                th->recv_ack = 0;
        } else {
                needs_ack = 1;
                th->recv_ack = htonl(ntohl(th->sent_seq) + 1 /* 1 means: th->syn + th->fin */
                        + tcplen - (th->data_off>>2));  /* oldskb seq+len */
                th->sent_seq = 0;
        }


        /* Set rst-ack flag */
        th->tcp_flags = TCP_FLAG_RST ;
        if(likely(needs_ack))
                th->tcp_flags |= TCP_FLAG_ACK;


        th->data_off = sizeof(struct tcp_hdr) << 2;
        th->rx_win = 0;
        th->tcp_urp = 0;


        /* Exchange ports */
        tmpport = th->dst_port;
        th->dst_port = th->src_port;
        th->src_port = tmpport;


        /* Exchange ip addr */
        tmpAddr = iph->src_addr;
        iph->src_addr = iph->dst_addr;
        iph->dst_addr = tmpAddr;


        iph->version_ihl = 0x45;
        iph->type_of_service = 0;
        iph->packet_id = 0x1314;
        iph->total_length = rte_cpu_to_be_16(sizeof(struct ipv4_hdr) + sizeof(struct tcp_hdr));
        iph->fragment_offset = rte_cpu_to_be_16(IP_DF);
        iph->next_proto_id = IPPROTO_TCP;
        iph->time_to_live = 128;
        iph->type_of_service = 0;
        iph->hdr_checksum = 0;


        mbuf->ol_flags |= PKT_TX_IP_CKSUM;
        mbuf->ol_flags &= ~PKT_TX_TCP_CKSUM;
        th->cksum = 0;
        th->cksum = get_ipv4_udptcp_checksum(iph,(uint16_t*)th);


        mbuf->pkt.vlan_macip.f.l2_len = sizeof(struct ether_hdr);
        mbuf->pkt.vlan_macip.f.l3_len = sizeof(struct ipv4_hdr);

0 0