Bug 133736 - [udp] ip_id not protected ...
Summary: [udp] ip_id not protected ...
Status: Closed Overcome By Events
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 7.0-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-04-14 22:10 UTC by Ernest Hua
Modified: 2019-02-01 15:21 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ernest Hua 2009-04-14 22:10:02 UTC
We have evidence of IP fragments from different UDP transactions being stamped with the same 16-bit id.

Fix: 

ip_id needs some atomic protection.

The same can probably be said of the random id generator.
How-To-Repeat: Using a multi-threaded application, transmit lots of large (much greater than MTU) UDP packets of the same size with known but distinctive content to a single destination port using a multi-core system as the transmitter.

There will be occasional data corruption found at the destination where data from one transaction is found in the payload of another transaction.
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2009-04-14 22:38:57 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-net

Over to maintainer(s).
Comment 2 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 07:59:43 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped
Comment 3 Tom Jones freebsd_committer freebsd_triage 2019-02-01 15:21:38 UTC
Hi,

I wrote a python test case that I think should exercise this. I didn't manage to hit this case, if you can reproduce this on a modern FreeBSD please reopen the bug. If you can add an exact reproduction case that would be very helpful. 


server:

#!/usr/bin/env python3                                                                
                                                                                      
import socket                                                                         
import sys                                                                            
                                                                                      
UDP_IP = "0.0.0.0"                                                                    
UDP_PORT = 5005                                                                       
                                                                                      
sock = socket.socket(socket.AF_INET, # Internet                                       
                     socket.SOCK_DGRAM) # UDP                                         
sock.bind((UDP_IP, UDP_PORT))                                                         
                                                                                      
peers = {}                                                                            
                                                                                      
while True:                                                                           
    data, addr = sock.recvfrom(2500)                                                  
    #sys.stdout.write(".")                                                            
    #sys.stdout.flush()                                                               
                                                                                      
    if addr in peers:                                                                 
        if data != peers[addr]:                                                       
            print("mismatch in recv'd data")                                          
            print("peer {} \n data: \t{} recvd: {}\t".format(addr, peers[addr], data))
            exit()                                                                    
        else:                                                                         
            peers[addr] = data                                                        

client:
#!/usr/bin/env python3

import socket
from multiprocessing import Process

def sendthread(ip, port, message):
    sock = socket.socket(socket.AF_INET, # Internet
                         socket.SOCK_DGRAM) # UDP

    while True:
        try:
            sock.sendto(message, (ip, port))
        except OSError as e:
           if e.errno == 55:
                pass

if __name__ == '__main__':
    ip = "137.50.17.240"
    port = 5005

    one = Process(target=sendthread, args=(ip, port, bytes("A" * 2000, encoding='ascii')))
    two = Process(target=sendthread, args=(ip, port, bytes("B" * 2000, encoding='ascii')))

    one.start()
    two.start()

    one.join()
    two.join()