A friendly reminder that TCP is a streaming protocol

polaris · · 368 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>So I just now defeated this <strong>ANNOYING AF</strong> issue due to my own ignorance. Basically the tl;dr is please keep in mind that TCP is a <strong>streaming</strong> protocol when getting fancy with raw connections.</p> <p>So here&#39;s the setup: I had a raw TCP connection that I wrapped in my own ReadWriter so I could create custom Write and Read methods that utilized some crypto functions to encrypt/decrypt data. So far so good right?</p> <p>Normally I&#39;d be able to call it a day. However I have been trying to speed code a new protocol for data transfer and decided I&#39;d use the gob package to speed up prototyping of this. Basically I didn&#39;t want to create packet-specific serialization just yet because <em>yawn</em> who has time for that. </p> <p>So, I am testing the protocol out and I get through discovery, no problem. Now on to key exchange... again no problem transferring data using the gob encoding. Now it comes time to create my crypto device and implement the encrypted form of my connection. A couple of test packets and SUCCESS!</p> <p>Okay well this isn&#39;t that exciting but still, things were working. Then I send another set of packets and suddenly I&#39;m getting an error related to the crypto device being unable to work properly. After some digging it turned out that the a public nonce I was transferring was inconsistently being encountered. </p> <p>I spent an hour verifying that the messages sent were correct and had the expected bytes. Now for those that aren&#39;t familiar with gob, basically it will send the type information first, then send the values (later just the type id and values after type info caching IIRC). One with my forgetfulness about TCP would expect this to be carried in two separate &#34;packets&#34; since they utilize separate write calls. Naturally I checked to ensure I had two separate calls to write. I did and they were of the expected lengths after encryption.</p> <p>MY MISTAKE (aside from remembering that TCP is inherently a stream protocol) was that I didn&#39;t immediately check what I was receiving on the other side of the connection, assuming two calls to Write() ended up with two packets. Finally out of frustration I decided to check and lo and behold I was getting a read length on the remote side of the connection that equaled the combined length of the two writes.</p> <p>This posed a problem because I was requiring that each write uses a separate set of conditions so that each could be decrypted on its own. Thus, when I received the combined packet, I was decrypting with only my first set of conditions over the whole of both sets I expected, generating what was essentially jibberish to the gob decoder.</p> <p>Now, the short-term fix for this is of course to append the expected length to correctly partition streamed data into packets, then decrypt, then decode. I patched this only 5 min. ago and it&#39;s working peachy but now I&#39;m regretting being lazy and not being more explicit about my data serialization and using Gob.</p> <p>So, to conclude: I&#39;m sure there are more elegant ways to do what I am trying to accomplish, however I attempted to use a custom ReadWriter with gob and in the end a TCP stream buffer screwed me over. My overall message is that if you have issues like I did with using specialized interfaces with other encoders/decoders over a connection, perhaps the issue is that the data is combining in the pre-transmission buffer then being transmitted together when you are expecting discrete packets over TCP. </p> <p>Happy coding I guess, I&#39;m gonna bang my head against the wall and give up one of my &#34;programmer&#34; cards. Cheers!</p> <hr/>**评论:**<br/><br/>danredux: <pre><p>This is pretty funny.</p> <p>You don&#39;t need to send any message-length type stuff, though. Just use a streaming encryption scheme instead of a message-based one.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

368 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传