/* * This sends a keep alive message to the specified IP. * It does not tag the packet with the Accelerator ID this * prevents the keepalive messages from recreating dead sessions * in remote Accelerators. */ void sendkeepalive (__u32 saddr, __u16 source, __u32 seq, __u32 daddr, __u16 dest, __u32 ack_seq){ char packet[BUFSIZE]; struct iphdr *iph = NULL; struct tcphdr *tcph = NULL; struct sockaddr_in sin, din; __u16 tcplen; memset(packet, 0, BUFSIZE); sin.sin_family = AF_INET; din.sin_family = AF_INET; sin.sin_port = source; din.sin_port = dest; sin.sin_addr.s_addr = saddr; din.sin_addr.s_addr = daddr; iph = (struct iphdr *)packet; iph->ihl = 5; // IP header length. iph->version = 4; // IP version 4. iph->tos = 0; // No TOS. iph->tot_len=htons(sizeof(struct iphdr) + sizeof(struct tcphdr)); // L3 + L4 header length. iph->id = 0; // What? iph->frag_off = 0; // No fragmenting. iph->ttl = 64; // Set a TTL. iph->protocol = IPPROTO_TCP; // TCP protocol. iph->check = 0; // No IP checksum yet. iph->saddr = saddr; // Source IP. iph->daddr = daddr; // Dest IP. tcph = (struct tcphdr *) (((u_int32_t *)iph) + iph->ihl); tcph->check = 0; // No TCP checksum yet. tcph->source = source; // Source TCP Port. tcph->dest = dest; // Destination TCP Port. tcph->seq = htonl(seq - 1); // Current SEQ minus one is used for TCP keepalives. tcph->ack_seq = htonl( ack_seq - 1); // Ummm not sure yet. tcph->res1 = 0; // Not sure. tcph->doff = 5; // TCP Offset. At least 5 if there are no TCP options. tcph->fin = 0; // FIN flag. tcph->syn = 0; // SYN flag. tcph->rst = 0; // RST flag. tcph->psh = 0; // PSH flag. tcph->ack = 1; // ACK flag. tcph->urg = 0; // URG flag. __set_tcp_option((__u8 *)iph,32,6,localID); // Add the Accelerator ID to this packet. tcplen = ntohs(iph->tot_len) - iph->ihl*4; tcph->check = 0; tcph->check = tcp_sum_calc(tcplen, (unsigned short *)&iph->saddr, (unsigned short *)&iph->daddr, (unsigned short *)tcph); iph->check = 0; iph->check = ip_sum_calc(iph->ihl*4, (unsigned short *)iph); if(sendto(rawsock, packet, ntohs(iph->tot_len), 0, (struct sockaddr *)&din, sizeof(din)) < 0){ printf("sendto() error\n"); } return; }
/* * This sends a keep alive message to the specified IP. * It does not tag the packet with the Accelerator ID this * prevents the keepalive messages from recreating dead sessions * in remote Accelerators. */ void sendkeepalive (__u32 saddr, __u16 source, __u32 seq, __u32 daddr, __u16 dest, __u32 ack_seq){ char packet[BUFSIZE]; struct iphdr *iph = NULL; struct tcphdr *tcph = NULL; //struct sockaddr_in sin; struct sockaddr_in din; __u16 tcplen; memset(packet, 0, BUFSIZE); //sin.sin_family = AF_INET; din.sin_family = AF_INET; //sin.sin_port = source; din.sin_port = dest; //sin.sin_addr.s_addr = saddr; din.sin_addr.s_addr = daddr; iph = (struct iphdr *)packet; iph->ihl = 5; // IP header length. iph->version = 4; // IP version 4. iph->tos = 0; // No TOS. iph->tot_len=htons(sizeof(struct iphdr) + sizeof(struct tcphdr)); // L3 + L4 header length. iph->id = 0; // What? iph->frag_off = 0; // No fragmenting. iph->ttl = 64; // Set a TTL. iph->protocol = IPPROTO_TCP; // TCP protocol. iph->check = 0; // No IP checksum yet. iph->saddr = saddr; // Source IP. iph->daddr = daddr; // Dest IP. tcph = (struct tcphdr *) (((u_int32_t *)iph) + iph->ihl); tcph->check = 0; // No TCP checksum yet. tcph->source = source; // Source TCP Port. tcph->dest = dest; // Destination TCP Port. tcph->seq = htonl(seq - 1); // Current SEQ minus one is used for TCP keepalives. tcph->ack_seq = htonl( ack_seq - 1); // Ummm not sure yet. tcph->res1 = 0; // Not sure. tcph->doff = 5; // TCP Offset. At least 5 if there are no TCP options. tcph->fin = 0; // FIN flag. tcph->syn = 0; // SYN flag. tcph->rst = 0; // RST flag. tcph->psh = 0; // PSH flag. tcph->ack = 1; // ACK flag. tcph->urg = 0; // URG flag. if (__set_tcp_option((__u8 *)iph,32,3,2) == -1) { // Add the Accelerator ID to this packet. LOGDEBUG(lc_sesman, "Sessioncleanup: Cannot add accelerator ID, sessioncleanup.c, IP datagram ID %x, current value of TCP doff %d",ntohs(iph->id), tcph->doff); } else { unsigned char *tcpdata = (unsigned char *) tcph + tcph->doff * 4; // Find starting location of the TCP data. pOpennopHeader oh = (pOpennopHeader) tcpdata; oh->opennopID = localID; oh->seqNo = 0; oh->compression = 0; oh->deduplication = 0; oh->reasonForNoOptimization = NOT_RELEVANT; oh->queuenum = 0; oh->pattern = OPENNOP_PATTERN; iph->tot_len = htons(ntohs(iph->tot_len)+sizeof(OpennopHeader)); } tcplen = ntohs(iph->tot_len) - iph->ihl*4; tcph->check = 0; tcph->check = tcp_sum_calc(tcplen, (unsigned short *)&iph->saddr, (unsigned short *)&iph->daddr, (unsigned short *)tcph); iph->check = 0; iph->check = ip_sum_calc(iph->ihl*4, (unsigned short *)iph); if(sendto(rawsock, packet, ntohs(iph->tot_len), 0, (struct sockaddr *)&din, sizeof(din)) < 0){ printf("sendto() error\n"); } return; }