Bitcoin Forum
September 25, 2018, 10:13:50 AM *
News: ♦♦ New info! Bitcoin Core users absolutely must upgrade to previously-announced 0.16.3 [Torrent]. All Bitcoin users should temporarily trust confirmations slightly less. More info.
 
   Home   Help Search Donate Login Register  
Pages: [1]
  Print  
Author Topic: Is there any reason why Messages are sent in 2 TCP Segments instead of 1?  (Read 639 times)
Coding Enthusiast
Sr. Member
****
Offline Offline

Activity: 503
Merit: 320


Novice C♯ Coder


View Profile WWW
August 01, 2017, 05:18:45 AM
 #1

This is the response I get after sending the Version message:
(this is from WireShark:
Code:
Frame 8: 180 bytes on wire (1440 bits), 180 bytes captured (1440 bits) on interface 0
[2 Reassembled TCP Segments (126 bytes): #6(24), #8(102)]
    [Frame: 6, payload: 0-23 (24 bytes)]
    [Frame: 8, payload: 24-125 (102 bytes)]
    [Segment count: 2]
    [Reassembled TCP length: 126]
    [Reassembled TCP Data: f9beb4d976657273696f6e00000000006600000085e1eb8d...]

My confusion is in two parts:
1. Why is it sending the response (the returned Version message) in 2 TCP Segments instead of 1? And will it always be header separate from message body?
2. Why is Verak message inside the same response and will it always be like this meaning multiple messages inside one response? (Have not yet gotten around testing other messages)

Projects List+Suggestion box
Donation link using BIP21
Bech32 Donation link!
BitcoinTransactionTool (0.9.2):  Ann - Source Code
Watch Only Bitcoin Wallet (supporting SegWit) (3.1.0):  Ann - Source Code
SharpPusher (broadcast transactions) (0.10.0): Ann - Source Code

1537870430
Hero Member
*
Offline Offline

Posts: 1537870430

View Profile Personal Message (Offline)

Ignore
1537870430
Reply with quote  #2

1537870430
Report to moderator
1537870430
Hero Member
*
Offline Offline

Posts: 1537870430

View Profile Personal Message (Offline)

Ignore
1537870430
Reply with quote  #2

1537870430
Report to moderator
1537870430
Hero Member
*
Offline Offline

Posts: 1537870430

View Profile Personal Message (Offline)

Ignore
1537870430
Reply with quote  #2

1537870430
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
1537870430
Hero Member
*
Offline Offline

Posts: 1537870430

View Profile Personal Message (Offline)

Ignore
1537870430
Reply with quote  #2

1537870430
Report to moderator
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 1526
Merit: 1656


3F1Y9yquzvY6RWvKbw2n2zeo9V5mvBhADU


View Profile WWW
August 01, 2017, 05:24:29 AM
 #2

1. Why is it sending the response (the returned Version message) in 2 TCP Segments instead of 1? And will it always be header separate from message body?
Because some optimizations were made where the header is queued to be sent first, then the payload if there is a payload. This results in two calls to the kernel, but it should still be received as one message chunk even though sent separately.

2. Why is Verak message inside the same response and will it always be like this meaning multiple messages inside one response? (Have not yet gotten around testing other messages)
Verack should not be part of the same response. It may be sent at the same time though, but multiple messages should not be in the same TCP packets.

Coding Enthusiast
Sr. Member
****
Offline Offline

Activity: 503
Merit: 320


Novice C♯ Coder


View Profile WWW
August 01, 2017, 06:15:25 AM
 #3

I'm new to TCP protocol so my terminology may be a bit wrong.
I am receiving the response over the same open socket but over 2 different calls (2 different buffers). 1 header 24 byte then 1 body variable byte [This was actually a source of big confusion for me]
Then looking deeper at WireShark I saw that line I shared above showing 2 different Segments.

This is what Wireshark shows (The text in red is added on photo):



Also in my code this is the hex of the total buffer I receive. It contains both messages:
Quote
f9beb4d976657273696f6e0000000000660000008a94bbe97f1101000d00000000000000131b80590000000 0010000000000000000000000000000000000ffff05ef60c22acf0d000000000000000000000000 0000000000ffff23a7f609208df65ca61c4a15f201102f5361746f7368693a302e31342e312f374 d070001f9beb4d976657261636b000000000000000000005df6e0e2

Projects List+Suggestion box
Donation link using BIP21
Bech32 Donation link!
BitcoinTransactionTool (0.9.2):  Ann - Source Code
Watch Only Bitcoin Wallet (supporting SegWit) (3.1.0):  Ann - Source Code
SharpPusher (broadcast transactions) (0.10.0): Ann - Source Code

theymos
Administrator
Legendary
*
expert
Offline Offline

Activity: 3150
Merit: 3702


View Profile
August 01, 2017, 06:50:40 AM
 #4

Upper-layer protocols like Bitcoin experience a TCP socket as a stream of bytes. So from a node's perspective, it writes to an outgoing stream per peer in a manner like "versionVerackAddrInvBlock...", with messages just stuck together, and a similar incoming stream per peer. The fact that things are actually broken up into packets by TCP isn't generally something that users of TCP have to worry about (except sometimes for optimization reasons). A Bitcoin message can be broken into multiple TCP packets (if it's too large for one), and a TCP packet can contain multiple Bitcoin messages (if Bitcoin Core happens to send two Bitcoin message very close together so that the OS can batch them). If you're interested in Bitcoin rather than TCP, then you shouldn't really worry about this: just stick all of the TCP payloads together.

Try writing a simple TCP server and client in C or something using the basic syscalls. It's pretty simple, and it'll give you more understanding of how it works from the perspective of a TCP user.

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
Coding Enthusiast
Sr. Member
****
Offline Offline

Activity: 503
Merit: 320


Novice C♯ Coder


View Profile WWW
August 01, 2017, 03:15:23 PM
 #5

If you're interested in Bitcoin rather than TCP, then you shouldn't really worry about this: just stick all of the TCP payloads together.

Try writing a simple TCP server and client in C or something using the basic syscalls. It's pretty simple, and it'll give you more understanding of how it works from the perspective of a TCP user.

I'm actually interested in both and kind of learning everything at the same time!
Your comment helped a lot as a matter of fact. I've changed my MessageManager class which is supposed to handle these received byte arrays and now it looks for the Magic in messages and based on first 24 byte of header and the PayloadSize inside of it, I decide how much of the packet is remaining or how to generally go on from there.

Now everything works fine and life is beautiful again after 1 week of struggling.
Thanks. Smiley

Projects List+Suggestion box
Donation link using BIP21
Bech32 Donation link!
BitcoinTransactionTool (0.9.2):  Ann - Source Code
Watch Only Bitcoin Wallet (supporting SegWit) (3.1.0):  Ann - Source Code
SharpPusher (broadcast transactions) (0.10.0): Ann - Source Code

Andre_Goldman
Sr. Member
****
Offline Offline

Activity: 322
Merit: 251

Property1of1OU


View Profile
August 02, 2017, 05:29:25 PM
 #6

If you're interested in Bitcoin rather than TCP, then you shouldn't really worry about this: just stick all of the TCP payloads together.

Try writing a simple TCP server and client in C or something using the basic syscalls. It's pretty simple, and it'll give you more understanding of how it works from the perspective of a TCP user.

I'm actually interested in both and kind of learning everything at the same time!
Your comment helped a lot as a matter of fact. I've changed my MessageManager class which is supposed to handle these received byte arrays and now it looks for the Magic in messages and based on first 24 byte of header and the PayloadSize inside of it, I decide how much of the packet is remaining or how to generally go on from there.

Now everything works fine and life is beautiful again after 1 week of struggling.
Thanks. Smiley

sounds to me that it is TCP Segmentation Offload.

Quote
Most modern operating systems support some form of network offloading, where some network processing happens on the NIC instead of the CPU. Normally this is a great thing. It can free up resources on the rest of the system and let it handle more connections.

https://wiki.wireshark.org/CaptureSetup/Offloading

Nice observation, thanks for your post. It let me thinking about OS detection and TCP/IP stack fingerprinting.

Patent1number: ****-****
Pages: [1]
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!