0

I have verified in wireshark that my TCP handshake SYN+ACK packet after receiving SYN packet is getting ignored

This is wireshark main view that shows within time wireshark read my SYN+ACK packet for RTT. but my linux socket api function connect acting dummy and send SYN again, Wht I need to do in this case I am attaching my wireshark packet times plus actual communication packets, I need someone with knowledge of this and C to answer this very much thanks

This is recorded time in wireshark when packets in attempted handshake are read

enter image description here

This is received packet in my program code

SYN

0000   45 00 00 3c fa ed 40 00 40 06 aa 5a c0 a8 0a 14
0010   c0 a8 0a 0f bc be 00 50 f8 08 9d 5b 00 00 00 00
0020   a0 02 fa f0 bb 0f 00 00 02 04 05 b4 04 02 08 0a
0030   9a 68 0f b0 00 00 00 00 01 03 03 07

ACK SYN with valid checksums, sequence number and acknowledgement number

0000   45 00 00 28 00 64 40 00 40 06 a4 f8 c0 a8 0a 0f
0010   c0 a8 0a 14 00 50 bc be 00 00 00 03 f8 08 9d 5c
0020   50 12 fa f0 cc f6 00 00

And this is my linux connect function complete dummy behavior by sending SYN again

0000   45 00 00 3c fa ee 40 00 40 06 aa 59 c0 a8 0a 14
0010   c0 a8 0a 0f bc be 00 50 f8 08 9d 5b 00 00 00 00
0020   a0 02 fa f0 b7 1b 00 00 02 04 05 b4 04 02 08 0a
0030   9a 68 13 a4 00 00 00 00 01 03 03 07

Can anyone please tell me how to handle this, since I am clueless on this, Is there any command that I can use to make my connect function TCP Handshake handling more attentive to my SYN+ACK packet and finally done with responding only ACK instead of playing plain stupid to send SYN again

As @LuisColorado mentioned to ask how am I generating the packet so the answer is this is how

this is my receiver thread that also transmit response TCP packets like SYN+ACK

void * receiver(void *data)
{

    //struct sockaddr_in cliaddr = {0};
    int recvlen = -1;
    int writelen = -1;
    //socklen_t clilen = sizeof(cliaddr);

    while (!_do_exit)
    {
        //recvlen = rrecvfrom(_udp_fd, buf, sizeof(buf), 0, (struct sockaddr*)&cliaddr, &clilen);
        char buf[VPN_MAX_MTU] = {0};
        char buf_1[VPN_MAX_MTU] = {0};
        memset(buf,0,VPN_MAX_MTU);
        memset(buf_1,0,VPN_MAX_MTU);
        memset(buf,0,VPN_MAX_MTU);
        memset(buf_1,0,VPN_MAX_MTU);
        

        char *str_source=malloc(18);
        char *str_dest=malloc(18);
        memset(str_source,0,18);
        memset(str_dest,0,18);
        recvlen=read(_tun_fd,buf,VPN_MAX_MTU);
        if(recvlen>0)
        {

    //BUFFER received here        
        struct iphdr *iph=(struct iphdr *)buf;  
        struct iphdr *ip=(struct iphdr *)buf_1;
        int y=0;
        for(int b=0;b<(sizeof(struct iphdr)+sizeof(struct tcphdr));b++)
        {
            if(y==20)
            {
                y=0;
                //printf("\n");
            }
            
            //printf("%x ",buf[b]<<24);
            
            
            y++;
        
        }
    //      tcph->check=(tcp_chksum(iph,tcph));
        //iph->check = csum(iph, sizeof(*iph));
        char str_src[18]={0};
        char str_dest_t[18]={0};
           
           
        //printf("IN %s %s\n",get_ip_str_1(iph->saddr,str_src),get_ip_str_1(iph->daddr,str_dest_t));
        memcpy(&ip->daddr,&iph->saddr,sizeof(uint32_t));
        memcpy(&ip->saddr,&iph->daddr,sizeof(uint32_t));
        //printf("OUT %s %s\n",get_ip_str_1(ip->saddr,str_src),get_ip_str_1(ip->daddr,str_dest_t));
        //Create ip
        
        //DOUBLE CHECK FOR BYTE ORDER
        
        //ip->tot_len=iph->tot_len;
        populate_ip_some(iph,ip);
        ip->tos=0;
        ip->tos=iph->tos;
        ip->ihl         = 5;
        ip->version     = 4;
        ip->tot_len     = htons(sizeof(struct iphdr) + sizeof(struct tcphdr));
        ip->protocol    = 6;
        ip->check=0; 
        //DOUBLE CHECK FOR BYTE ORDER
        ip->id=htons(100);
            ip->check = htons(csum(ip, sizeof(*ip)));


        //printf("before %d \n",htons(iph->check));
        iph->check=0; 
        //printf("middle %d\n",iph->check);
        //DOUBLE CHECK FOR BYTE ORDER
            iph->check = htons(csum(iph, sizeof(*iph)));

        int i=iph->ihl*4;
        struct tcphdr *tcph=(struct tcphdr *)(buf+i);
        //printf("tcp before %x\n",htons(tcph->check));
        tcph->check=0;
        printf("TCP START\n");
        tcph->check=(tcp_chksum(iph,tcph));
            printf("TCP END\n");
        //printf("tcp after %d\n",(tcph->check));
        //printf("i == %d\n",i);
        //POSSIBLY PRINT IPH for fun
        //for(int a=0;a<recvlen;a++)
            //printf("%x\n",buf[a]);
        //GET ihl SEND --  tcp
        int j=(ip->ihl*4);
        //printf("j == %d\n",j);
        int x=0;
        
        //SEEK filling
        struct tcphdr *tcp=(struct tcphdr *)(buf_1+20);
        //populate_tcp_some(tcph,tcp);//Do LOOK AT THIS FUNCTION TO [SEE/CORRECT IT] >:)
        if(tcph->syn==1)
        {
               printf("WHAT THE HELL THEN WHY\n");  
               printf("syn\n");
               populate_tcp_some(tcph,tcp);
               tcp->seq=htonl(1);
              // tcp->ack_seq=1;
               tcp->syn=1;
               tcp->ack=1;
               tcp->res1=0;
               tcp->res1=0;
               tcp->urg=0;
               tcp->psh=0;
               tcp->fin=0;
               tcp->doff=5;
               tcp->source=htons(80);
               int xx=ntohl(tcph->seq)+1;
               printf("\n\nfwdfwdfwd FAWAD %x\n\n",xx);
               tcp->ack_seq=htonl(xx);
    //         printf("received tcp syn = %d\n",tcph->syn);
        }
        else
        {
               populate_tcp_some(tcph,tcp);
               tcp->syn=0;
               tcp->ack=1;
               tcp->seq=htonl(1);
               tcp->res1=0;
               tcp->res1=0;
               tcp->urg=0;
               tcp->psh=0;
               tcp->fin=0;
               tcp->doff=5;
               tcp->ack_seq=htonl(ntohs(tcph->seq)+1);
    //         printf("sending tcp syn = %d ack = %d\n",tcp->syn,tcp->ack);
           
        }
        
        printf("syn=%d | ack = %d | fin = %d | %d seq = %d ack_seq = %d | urg = %d  | doff = %d | psh = %d rst = %d | rst2 = %d\n",tcp->syn,tcp->ack,tcp->fin,tcp->seq,tcp->ack_seq,tcp->urg,tcp->doff,tcp->psh,tcp->res1,tcp->res2);
        //populate_tcp_some(tcph,tcp);
        tcp->dest=tcph->source;
        tcp->window=htons(40);//tcph->window;
        //tcp->ack_seq=tcph->seq;
        //printf("%d %d SOURCE PORT \n",ntohs(tcph->source),ntohs(tcp->dest));
        
        tcp->source=htons(80);
        printf("%d %d PORTS \n",ntohs(tcp->source),ntohs(tcp->dest));
        tcp->check=0;
        //TCP CHECKSUM ABOUT TRIPPLE WOW
        tcp->check=htons(tcp_chksum(ip,tcp));
        
        //printf("tcpH = %d |  tcp = %d\n",tcph->check,htons(tcp->check));
        //IF needed make payload data
        //WRITE
        if (recvlen > 0) 
        {
            writelen = write(_tun_fd, buf_1, sizeof(struct iphdr)+sizeof(struct tcphdr));
            //debug("SR:%04d\n", recvlen);
            //debug("TW:%04d\n", writelen);
            
            if (writelen < 0) 
            {
            //debug("%s: rwrite() %s [%d]\n", _progname, strerror(errno), errno);
               //break;//NO NEED
            }
        }
        else if (recvlen < 0) 
        {
            //debug("%s: rrecvfrom() %s\n", _progname, strerror(errno));
               //break;//NO NEED
        }
        else if (recvlen == 0) 
        {
            //why
        }
    //FINALLY THEN SEND || DO WIRE SHARK 
        }
        
        // ...:)__ :) __:) ___:)___ (: __(:__ (;...  

    }

    debug("** Receiver ending.\n");
    pthread_exit(NULL);
}
user786
  • 3,902
  • 4
  • 40
  • 72
  • to be more attentive just see this sequence number `f8 08 9d 5b` in last and first packet in my dump for SYNs, wireshark read my SYN+ACK but my connect function keep sending same sequence number again and again. – user786 Jan 01 '22 at 09:34
  • 1
    Are you sure that the packets you send are even received at the other end? On which side did you do the packet capture? – Steffen Ullrich Jan 01 '22 at 09:51
  • @SteffenUllrich my client is using Tcp socket to send syn and my server is getting ip packets from TUN interface. So on my server is not bound to any port. I believe if I am sending valid Syn+Ack packets from server than all is good and answer ur question that `are u sure that the packets u send are even received at the server end` do u mean I need to attach my server to some port too. But that will kill the objective of the whole this thing because I like to simulate userspace tcp – user786 Jan 01 '22 at 10:01
  • I'm not asking about the server end but about the **other** end - which would be the client, i.e. the one sending the SYN. If the client does not receive your SYN+ACK then of course it will repeat the SYN. So better do a packet capture on the client side. – Steffen Ullrich Jan 01 '22 at 10:04
  • @SteffenUllrich `So better do a packet capture on the client side.` and how would I do this. My client is using tcp stream socket and it's connection function does not get successful. My client program stays at connect function and this might be because connect function complete handshake then it get succeed. My client program hangs at connect function call – user786 Jan 01 '22 at 10:21
  • 2
    A packet capture on the client side is done the same way as a packet capture on the server side, which you seem to be able to do. I.e. use some tool like tcpdump, wireshark etc to sniff on the clients network interface. – Steffen Ullrich Jan 01 '22 at 10:37
  • @SteffenUllrich do u mean I need to create ip layer socket on client side and use read function to check if my `SYN + ACK` packets are getting read in the client which is sent from server using interface tun0. Can u please tell. Plus yes I am using wireshark. – user786 Jan 01 '22 at 10:58
  • No, I mean that you use tools like tcpdump and wireshark to capture the traffic on the client side. Given that you already use wireshark I would expect that it is clear what to do for this on the client side. – Steffen Ullrich Jan 01 '22 at 11:15
  • @SteffenUllrich `..that you use tools like tcpdump...to capture the traffic on the client side` I am getting client packets in wireshark as I posted it as my syn packet dump in the question. My client using Stream socket plus also using tun0 interface with help of ifreq and setsockopt. My server created the tun0 interface and I am reading clients packet with help of `tun_fd` for created tun0 interface. So what ever packets My client send I get in the server because both connected 2 tun0 interface. And I am sniffing packets on tun0 interface in wireshark I see both the client and server packets – user786 Jan 01 '22 at 11:30
  • See my last comment so what else can I do. I have client and I am simulating tcp server. What else r u mention me to add. Problem is my client connect function is not getting succeed after I see my server respond to the client Syn packet with Syn + Ack packet. My client is simply ignoring my server's Syn + Ack reponse packet – user786 Jan 01 '22 at 11:33
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/240627/discussion-between-steffen-ullrich-and-user786). – Steffen Ullrich Jan 01 '22 at 11:44
  • How are you producing that packet. Seq=0 is a very strange case, that let's me think you are generating that packet with a low access raw socket. I don't know if your wireshark is reoffsetting the packet sequence numbers but a tcpdump output probably will be better.... as many things can be happening here. (even a packet filter in your linux server) So better clarify how are you producing your packets, as they normally don't fail if they are correct. – Luis Colorado Jan 02 '22 at 11:58
  • @LuisColorado I can share the code how I am generating sequence number. can U look at it? – user786 Jan 02 '22 at 12:03
  • @LuisColorado yes I am getting IP packets by reading TUN interface. And simulating in my code a listening port at port 80 so If I get SYN packet from clients I respond with SYN+ACK packet, So its simple simulation of listening port that I am trying to accomplish to see more info see my second last question https://stackoverflow.com/questions/70554352/running-my-code-that-creates-tun-interface-and-simulating-tcp-listening-port-in – user786 Jan 02 '22 at 12:22
  • Have you IP configured on that interface? that's important as you are conflicting with normal IP stack if you have IP configured on it. This can be the reason for you to be ignored, if TCP stack has no idea of a socket configured to accept those packets. – Luis Colorado Jan 03 '22 at 20:32
  • @LuisColorado interface is TUN0 that is attached to 192.168.10.20 so this is the IP of TUN0 interface.On client I am attached my client socket to this TUN0 interface with the help of ifr_req with setsockopt.And Destination port is 192.168.10.15&destination port is 80.This ip does not exists on my computer neither port is listening.But I am intercepting these packets for destination ip and port & responding to them using lower layer socket and TUN0 interface.Are u saying I need to configure this client's destination ip (192.168.10.15)on my system plus also configure dest port? How to do this? – user786 Jan 04 '22 at 05:36
  • then you have ip attached to it and probably tcp also attached. When you receive a packet on the TUN0 interface, both (your process and tcp) receive it, and probably both (your process and tcp) answer to it (if it is well formed) – Luis Colorado Jan 04 '22 at 10:47
  • @LuisColorado no TCP program is listening on port 80 besides my port listening simmulation over IP – user786 Jan 04 '22 at 11:17
  • yeah, but TCP module will issue an ICMP port unreachable message as a result of that. Not having a process listening only makes you to receive that error as tcp works as if it was the only handling TCP ports on the system. That ICMP will probably run in parallel to your system with your SYN/ACK packet and will make your client to process the first one arriving at it. – Luis Colorado Jan 04 '22 at 13:05
  • @LuisColorado is there a work around this issue. Or I am lost on this – user786 Jan 04 '22 at 14:13
  • @LuisColorado I tried to disable icmp unreachable message with `iptables -I OUTPUT -p icmp --icmp-type destination-unreachable -j DROP` still retransmission on both end of SYN and SYN+ACK. any idea what might be now, Its not what I tought – user786 Jan 04 '22 at 14:45
  • You can avoid the ICMP emission but as soon as the sequential numbers or the acknowledges don't mattch a RST tcp packet will be emited by one side. – Luis Colorado Jan 04 '22 at 18:27

0 Answers0