TCP segment of a reassembled PDU length 1 - database

I have timeout errors in a Oracle database and when I sniff it using Wireshark I get a packet with the following info: TCP segment of a reassembled PDU.
It has this TCP information:
Transmission Control Protocol, Src Port: ncube-lm (1521), Dst Port: 57861 (57861), Seq: 1, Ack: 1, Len: 1
I have 10 packets more with the same origin and destination as the mentioned above.
After the first packet with info 'TCP segment of a reassembled PDU' there come 9 identical packets:
2728 596.537143000 10.XX.XX.XX 10.YY.YY.YY TCP 55 [TCP Keep-Alive] ncube-lm > 57861 [ACK] Seq=1 Ack=1 Win=258 Len=1.
Then I have one last packet:
2746 605.585011000 10.XX.XX.XX 10.YY.YY.YY TCP 54 ncube-lm > 57861 [RST, ACK] Seq=2 Ack=1
Win=0 Len=0
This last packet appears at the exact time when the timeout occurs in the database.
How can a length 1 packet having been reassembled? Why does it have been reassembled when it comes from our own local machine?
This packet's source its our Oracle database (port 1521). Why does it send a packet with one byte of data (with value '00')?
Thank you!

By default the keep-alive(tcp_keepalive_probes) probe count is 9. The machine has sent 9 keep-alive probes but didn't get any response from the other end so it has reset the connection.

Usually, TCP packets with a len of 1 are control packets (ACK,SYN,FIN,RST). I'm guessing this is the case you encountered.
Moreover, the Wireshark packet extra info (in your case - 'TCP segment of a reassembled PDU') sometime labels packets incorrectly, so you should not rely on it entirely.
I don't think these packets are the reason for the timeout issue. could you supply more info about the rest of the session and the packets timing?

Related

Question about parallel execution of printf in a multi-threaded program

I made a program that sends and receives files between two hosts through multi-thread.
The program works normally, but I am worried about the performance of this program.
I call printf quite a lot to show the information and transfer rate of the file to be transferred to the console. When proceeding without any separate action, there was a problem in that the printf of the two threads overlapped to cover each other's text.
The result I want
[TCP Server] 1 Client Connected: IP Address=127.0.0.1, Port Number=53423
FileName:HDT.exe, FileSize:79202368
Percent : 100.00%
[TCP Server] 1 client disconnected: IP Address =127.0.0.1, Port Number=53423
// The output of the upper part and the output of the lower part shall be simultaneously performed.
[TCP Server] 2 Client Connected: IP Address=127.0.0.1, Port Number=53425
FileName:HDT.exe, FileSize:79202368
Percent : 100.00%
[TCP Server] 2 client disconnected: IP Address =127.0.0.1, Port Number=53425
But there is this problem
[TCP Server] 1 Client Connected: IP Address=127.0.0.1, Port Number=53209
FileName:HDT.exe, FileSize:79202368
Percent : 90.63%% FileSize:79202368 Address=127.0.0.1, Port Number=53211
Percent : 90.63%
[TCP Server] 1 client disconnected: IP Address =127.0.0.1, Port Number=53209
// The transmission rate of two clients is also output to a cursor that outputs a transmission rate of one client, and the output is messed up.
Percent : 100.00%
[TCP Server] 2 client disconnected: IP Address =127.0.0.1, Port Number=53211
So I used CRITICAL_SECTION object like this
EnterCriticalSection(&cs);
cur.Y = thread_number * 6 + 2; // Cur is a COORD variable that stores zero as an x member.
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Cur); // Move the cursor position of the console before outputting for a smooth output.
// curProgress value is the size of the current file transferred.
// totalProgress value is stored by receiving the total file size from the other host before the file is transmitted.
printf("Percent : %2.2f%%", (curProgress / totalProgress) * 100.0f);
LeaveCriticalSection(&cs);
I also called EnterCriticalSection to notify the name of the file to be transferred or that the transfer has ended.
There is no problem with the operation of the program, but I think it is very bad for performance.
Is there really no way to efficiently print out multiple prints on different lines without using lock?
I also tried ANSI commands such as \033[;H, but the problem was not resolved.

socket connect function use 4 handshake?

i start a server listening on 9877
then i try to connect this server on the same machine
but when connnected
i captured 4 times round trip , confused
kernel version Darwin sifang.local 19.6.0 Darwin Kernel Version 19.6.0: Mon Aug 31 22:12:52 PDT 2020; root:xnu-6153.141.2~1/RELEASE_X86_64 x86_64
machine :macbook pro 2020
listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes
12:57:42.981579 IP localhost.51188 > localhost.9877: Flags [S], seq 4266424528, win 65535, options [mss 16344,nop,wscale 6,nop,nop,TS val 2395708763 ecr 0,sackOK,eol], length 0
12:57:42.981647 IP localhost.9877 > localhost.51188: Flags [S.], seq 3797230557, ack 4266424529, win 65535, options [mss 16344,nop,wscale 6,nop,nop,TS val 2395708763 ecr 2395708763,sackOK,eol], length 0
12:57:42.981656 IP localhost.51188 > localhost.9877: Flags [.], ack 1, win 6379, options [nop,nop,TS val 2395708763 ecr 2395708763], length 0
12:57:42.981661 IP localhost.9877 > localhost.51188: Flags [.], ack 1, win 6379, options [nop,nop,TS val 2395708763 ecr 2395708763], length 0
The first 3 lines of your tcpdump output are the 3-way handshake.
The fourth line is just the server sending out an ACK for some reason. Note that the first line is from port 51188 to port 9877 (client to server SYN), while the second line is from port 9877 to port 51188 (server to client SYN+ACK), the third line is from port 51188 to port 9877 (client to server ACK, ending the 3-way handshake), and the fourth line is from port 9877 to port 51188 (server to client, not a copy of the client to server ACK).
That doesn't happen with an Ubuntu server; this is probably either a difference between the macOS and Linux TCP implementations or in the SSH daemons being used.
I determined this by running tcpdump on a Linux machine and telnetting to port 22 on a Mac (so the loopback device isn't involved); the same four packets (3-way handshake plus extra ACK) showed up.
(No, packets sent on the loopback interface aren't seen twice when capturing traffic on all operating systems. They're seen twice if you're capturing traffic on Linux, but libpcap filters out the outgoing copy in its packet reading code. They are not seen twice on macOS - or other BSD-flavored OSes.
The capture mechanisms in Linux and macOS/*BSD are different:
Linux uses PF_PACKET sockets, which deliver both incoming and outgoing copies of packets on the loopback interface, but they look identical, with the same source and destination ports, so if libpcap didn't discard the outgoing copy, you'd see two identical packets, but libpcap discards the outgoing copy, so you see only one;
macOS/*BSD/Solaris 11/AIX use BPF devices, which deliver only one copy of packets on the loopback interface, so there's no copy to discard.)

Synthesizing Packets with Scapy

Today, I was handed a 300 million entry csv file of netflow records, and my objective is to convert the netflow data to synthesized packets by any means necessary. After a bit of researching, I've decided Scapy would be an incredible tool for this process. I've been fiddling with some of the commands and attempting to create accurate packets that depict that netflow data, but I'm struggling and would really appreciate help from someone whose dabbled with Scapy before.
Here is an example entry from my dataset:
1526284499.233,1526284795.166,157.239.11.35,41.75.41.198,443,55915,6,1,24,62,6537,1419,1441,32934,65535,
Below is what each comma separated value represents:
Start Timestamp (Epoch Format): 1526284499.233
End Timestamp (Epoch Format): 1526284795.166
Source IP: 157.239.11.35
Destination IP: 41.75.41.198
IP Header Protocol Number: 443 (HTTPS)
Source Port Number: 55915
Destination Port Number: 6 (TCP)
TOS Value in IP Header: 1 (FIN)
TCP Flags: 24 (ACK & PSH)
Number of Packets: 62
Number of Bytes: 6537
Router Ingress Port: 1419
Router Egress Port: 1441
Source Autonomous System: 32934 (Facebook)
Destination Autonomous System: 65535
My Current Scapy Representation of this Entry:
>>> size = bytes(6537)
>>> packet = IP(src="157.240.11.35", dst="41.75.41.200", chksum=24, tos=1, proto=443) / TCP(sport=55915, dport=6, flags=24) / Raw(size)
packet.show():
###[ IP ]###
version= 4
ihl= None
tos= 0x1
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= 443
chksum= 0x18
src= 157.240.11.35
dst= 41.75.41.200
\options\
###[ TCP ]###
sport= 55915
dport= 6
seq= 0
ack= 0
dataofs= None
reserved= 0
flags= PA
window= 8192
chksum= None
urgptr= 0
options= []
###[ Raw ]###
load= '6537'
My Confusion:
Frankly, I'm not sure if this is right. Where I get confused is that the IP Protocol Header is 443, indicating HTTPS, however the destination port is 6, indicating TCP. Therefore, I'm not sure if I should include TCP or not, or if including the proto IP attribute is gratuitous. Furthermore, I'm not sure if Raw() is the correct way to include the size of each packet, let alone if I defined size in a proper manner.
Please be so kind as to let me know where I've gone wrong, or if I actually miraculously created a perfect synthesized packet for this particular entry. Thank you so much!
I think the columns might be wrong. HTTPS is TCP port 443 (usually), so the protocol number should be 6 (TCP) and one of the ports should be 443. My GUESS is that 443 is the source port, since the source IP belongs to Facebook, making 55915 the destination port. So, I think the columns there go: source IP, dest IP, source port, dest port, protocol.

question related to sockets in network programming with C

There is a system call known as socket(); it creates a socket on the listening server.
What I want to understand is a server creates an IP+port combination.
Let us say telnet uses port 23.
Now when the client machines do connections then the port on which the server is listening then the connection there is not on port 23 in fact it is on a different port.My confusion is
on the server side also does the same thing happen.
For example I write a server to listen to port 23 then the connections which will be done on server side with different clients how are they differentiated because all of them will be on same port.So how can you make so many connections on the same server port.If some one uses
telnet (23) or ftp (21) or ssh (22) then many people can still login to the same service port on the server i.e. more than one connection for ssh by different users where as ssh is listening only at port 22.So what exactly does the socket do or how is a socket created?
UPDATE
I got what is explained.Depending upon the IP+port combination from the client machine where the connection originated rest of the things by the server side can be handled and I think this information probably is used by socket file descriptors. What I see is in connect() system call which we use as follows
connect(sockfd,(struct sockaddr *)&client_address,size_t);
we do pass on struct sockaddr * at the client end which has unique IP+port combination I think when server gets this in accept then things proceed.
What I want to know further is the argument at server side
accept(server_sockfd,(struct sockaddr *)&client_address,(size_t *)sizeof (struct sockaddr ));
Does it get that same client_address which from client side was passed on using connect()
system call? If yes then the socket_descriptors for the same server listening to many clients are different.What I want to know is how does the data structure at the server side is maintained when it accepts a request from the client.
The unique combination that identifies the connection is:
Source address and port
Destination address and port
In your example the destination address and port are the same for many connections, but each comes from a unique combination of source address and port.
Here is a brief tcpdump session of me connecting from my desktop to my server via FTP (port 21):
22:55:50.160704 IP 172.17.42.19.64619 > 172.17.42.1.21: S 2284409007:2284409007(0) win 8192 <mss 1460,nop,nop,sackOK>
22:55:50.160735 IP 172.17.42.1.21 > 172.17.42.19.64619: S 1222495721:1222495721(0) ack 2284409008 win 65535 <mss 1460,sackOK,eol>
22:55:50.160827 IP 172.17.42.19.64619 > 172.17.42.1.21: . ack 1 win 8192
22:55:50.162991 IP 172.17.42.1.21 > 172.17.42.19.64619: P 1:61(60) ack 1 win 65535
22:55:50.369860 IP 172.17.42.19.64619 > 172.17.42.1.21: . ack 61 win 8132
22:55:56.288779 IP 172.17.42.19.64620 > 172.17.42.1.21: S 3841819536:3841819536(0) win 8192 <mss 1460,nop,nop,sackOK>
22:55:56.288811 IP 172.17.42.1.21 > 172.17.42.19.64620: S 454286057:454286057(0) ack 3841819537 win 65535 <mss 1460,sackOK,eol>
22:55:56.288923 IP 172.17.42.19.64620 > 172.17.42.1.21: . ack 1 win 8192
22:55:56.290224 IP 172.17.42.1.21 > 172.17.42.19.64620: P 1:61(60) ack 1 win 65535
22:55:56.488239 IP 172.17.42.19.64620 > 172.17.42.1.21: . ack 61 win 8132
22:56:03.301421 IP 172.17.42.19.64619 > 172.17.42.1.21: P 1:12(11) ack 61 win 8132
22:56:03.306994 IP 172.17.42.1.21 > 172.17.42.19.64619: P 61:94(33) ack 12 win 65535
22:56:03.510663 IP 172.17.42.19.64619 > 172.17.42.1.21: . ack 94 win 8099
22:56:06.525348 IP 172.17.42.19.64620 > 172.17.42.1.21: P 1:12(11) ack 61 win 8132
22:56:06.526332 IP 172.17.42.1.21 > 172.17.42.19.64620: P 61:94(33) ack 12 win 65535
22:56:06.726857 IP 172.17.42.19.64620 > 172.17.42.1.21: . ack 94 win 8099
You can see the initial connection is 172.17.42.19.64619 <-> 172.17.42.1.21. Port 64619 is what the Windows 7 box happened to select as the source port when it made the outgoing connection. The two lines with S are the SYN packets going back and forth to establish the connection. Then I start the next connection and Windows just uses the next available port, 64620. The connection 172.17.42.19.64620 <-> 172.17.42.1.21 forms a new unique tuple of the items I listed at the top. Only the client's port is different, but that's enough. Each packet that arrives at the server to port 21 can be distinguished by the source port. Each packet from port 21 on the server arriving at the client can be distinguished by the destination port.
TCP connections are identified by 4 parameters:
local IP
local port
remote IP
remote port
So, even if two connections share the same local IP and port, the OS can differentiate between then because the remote IP and/or port are going to be different.
I will give you pseudo code from Qt to explain the matter. All TCP servers work in same way.
You first create a listening TCP server socket. When an incoming connection request arrives the operating system creates a new socket (your OS uses a different port than listening socket) and associates this new socket with the remote client for you. The TCP server socket continues to accept new connections and you resume your communication with the remote peer via the newly created socket.
tcpServer.listen(LocalHost, PORT);
connect(&tcpServer, SIGNAL(newConnection()),this, SLOT(NewConnection()));
//Callback that is called when server accepts a new connection
void NewConnection()
{
//Here you will have a new socket for communication with the client
//The tcpServer will continue listening to given port
QTcpSocket* connection = tcpServer.NextPendingConnection();
//Use your new connection to communicate with the remote client...
}
I hope this helps

Handshake with spoofed IP

I noticed some legit connection is like this:
6221 29.880628 5.4.3.2 1.2.3.4 TCP 61235 > cbt [SYN] Seq=0 Win=8192 Len=0 MSS=1452 SACK_PERM=1
6222 29.880646 1.2.3.4 5.4.3.2 TCP cbt > 61235 [SYN, ACK] Seq=0 Ack=1 Win=16384 Len=0 MSS=1460 SACK_PERM=1
6240 29.984383 5.4.3.2 1.2.3.4 TCP 61235 > cbt [ACK] Seq=1 Ack=1 Win=65340 Len=0
6241 29.989707 5.4.3.2 1.2.3.4 TCP 61235 > cbt [PSH, ACK] Seq=1 Ack=1 Win=65340 Len=267
So, at least in my case, if legit is always like this:
Client (Syn,Seq=0)
Server (Syn/Ack, Seq=0, Ack1)
Client (Ack, Seq=1, Ack1)
Seemed weak to me in regards of being possible to spoof and able to raise the socket up to the application. (of course spoofed IP must be down in order to avoid the RST)
So I tested sending a SYN with spoofed IP and then send the ACK.
The SYN arrives, but the ack gets like ignored til sometime.
After the spoofed SYN, the server sends 3 SYN/ACK (with no reply, of course). After some seconds if I re-send the ack, it will receive but with some error.
Is it possible to handshake with a spoofed IP in this scenario? Seems to be, but im doing something wrong..
No, it is not possible.
The problem is when the server sends back the SYN-ACK -- because it sends it back to the spoofed ip, which would not match the actual originator of the message.
Specifically, what you describe (faking the ACK) is a TCP sequence prediction attack which is well known and is countered in pretty much every OS nowadays.

Resources