Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-26538

QUdpSocket: connectToHost() resets local port number specified by bind()

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 5.5.0 Alpha, 5.5.0
    • 4.7.4, 5.2.0
    • Network: Sockets
    • None
    • Debian Sid, amd64
    • 9fb68a90af79df3b8dc3225a3a97e2c6387afeec

    Description

      Consider the following code snippet (port numbers and ip address are arbitrary):

      #include<QtNetwork/QUdpSocket>
      #include<QCoreApplication>
      #include<QDebug>
      
      int main(int argc, char* argv[])
      {
          QCoreApplication(argc, argv);
      
          QUdpSocket s;
          s.bind(10000);
          qDebug() << "Local port before connectToHost()" << s.localPort();
      
          s.connectToHost(QHostAddress("87.250.251.3"), 20000);
          qDebug() << "Local port after connectToHost()" << s.localPort();
      
          s.write("ping!");
      
          return 0;
      }
      

      The output of the program is

      Local port before connectToHost() 10000
      Local port after connectToHost() 55154
      

      which means that local port binding made by bind() is undone by connectToHost(). tcpdump shows that indeed the udp packet is sent with randomly assigned source port. This behavior is not documented in the documentation for QUdpSocket and I consider it as a bug because it is not consistent with behavior of Berkley sockets. With Berkley sockets it is possible to bind() a udp socket first, then specify a default peer with connect(), then send data using send() or write(); connect() does not rebind a socket if it is already bound.

      POSIX specifically allows this behavior: «If the socket has not already been bound to a local address, connect() shall bind it to an address which, unless the socket's address family is AF_UNIX, is an unused local address.
      If the initiating socket is not connection-mode, then connect() shall set the socket's peer address, and no connection is made. For SOCK_DGRAM sockets, the peer address identifies where all datagrams are sent on subsequent send() functions, and limits the remote sender for subsequent recv() functions.» (extracted from description of connect() of POSIX-2008).

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              thiago Thiago Macieira
              mbalabin Mikhail Balabin
              Votes:
              5 Vote for this issue
              Watchers:
              12 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes