DTLS listen

Developers
aFeLiOn
2010-07-27
2013-04-23
  • aFeLiOn
    aFeLiOn
    2010-07-27

    I am writing client/server that send file using DTLS (Cyassl).
    Try with code as in echoserver in example, each time data received, it should re-bind again.
    Tried not to close socket but still not receive data anymore.

    Is there able to keep the socket listener?

     
  • Todd Ouska
    Todd Ouska
    2010-07-27

    Why are you using DTLS for file transfer?  DTLS is typically for streaming applications where missing parts of the data don't matter.  If you want the file to be complete you need to use TLS instead.

    UDP sockets don't listen, though they can connect to an address.

    Pay close attention to the echoserver and echoclient example.  You can run the echoserver in DTLS mode if you build CyaSSL with DTLS with -enable-dtls .  Then you can run the echoclient from examples/echoclient with DTLS and exchange a file like this:

    ./echoclient input

    where input is a text file with some source code.

     
  • aFeLiOn
    aFeLiOn
    2010-07-28

    in echoserver.c, line 154, server loop:
            SSL_shutdown(ssl);
            SSL_free(ssl);
            CloseSocket(clientfd);
    #ifdef CYASSL_DTLS
            tcp_listen(&sockfd);
            SignalReady(args);
    #endif

    The socket is re created, and bind on the address again.
    How to keep the current socket?

     
  • aFeLiOn
    aFeLiOn
    2010-07-29

    Any help?
    I have problems when handing multi connections to a DTLS server.

    server:
    Call recvfrom to listen new connection
    When a SSL accepted, call SSL_read to retrieve data.
    If I want to keep that connection for future transfering, the server can not back recvfrom new connections.
    If I put SSL_read in another thread, and continue bind the socket again, then got error "Address already in use".

    So how to handle multi clients in UDP server?
    Thanks in advance.

     
  • Todd Ouska
    Todd Ouska
    2010-07-29

    Are you sure you want DTLS?  UDP servers are iterative and connectionless.  You indicate you want a concurrent connection oriented server, that means TCP and TLS.

    The example echoserver is iterative, as a UDP server should be.

    You could try making it concurrent but I think you'll find it much easier to just use TLS instead.

     
  • Todd Ouska
    Todd Ouska
    2010-07-30

    SNMP over UPD makes sense.  One questions, one answer… iterative server.  No TCP startup or teardown.

    DTLS over SNMP doesn't make sense, the DTLS handshake has extra steps over TLS negating the benefit of no TCP.  And a concurrent server is now needed.

    The right answer in this case is use TLS.

    All of the things wrong with DTLS over SNMP are discussed in the link you provide.  They're not unique to OpenSSL's implementation, it's just a poor choice.

    A bad alternative is to have an iterative UDP server get a request, spawn a worker thread with a new port and send that port back to client who then connects with DTLS to the port returned.  Many clients, many server worker threads (or whatever).  I suggest doing that if you have to use DTLS.

    CyaSSL doesn't yet allow the user to directly write to the input output buffers.  But if you feel like must do that feel free to add the changes.  I'll try to help if I can.

     
  • aFeLiOn
    aFeLiOn
    2010-08-22

    Thanks for your answer. Today I have time back to the implementation and have to bother you again.

    * Server
    1. Create an UDP socket, binding on localhost. Create server CTX, SSL.
    2. Start new thread, loop forever, using select() to wait new connection:
    select(fd + 1, &fds, NULL, NULL, NULL);
    and recvfrom to read UDP connect (echoserver.c)
    3. When has a new connection, create new SSL and do SSL_accept.
    If connection is accepted, and save its SSL, address/port in a connected list
    4. Do SSL_read to get data, and call this connection callback to handle the data.
    5. Data responded is write to this connection SSL object (SSL_write)
    6. Back to select() for new connections.
    7. When has another connection (bypass select()), search its address/port in the connected list; if found, get the SSL saved, skip SSL_accept, back to step 4, otherwise, do SSL_accept and add to the list.

    * Client
    1. Create an UDP socket, new client CTX, SSL.
    2. Do SSL_connect, if success, start a new thread waiting response data.
    3. Send data (SSL_write) in main thread.

    The above code is worked if I have only ONE client connects to the server, send, recv ok between that client and server.
    But if I create new client process, SSL_connect always returns error SOCKET_ERROR_E (tried in both Windows, Linux, and NON_BLOCKING mode).
    Server do not pass the select() waiting for the second client.

    I used certs files from Cyassl source, CTX created success
    * Server:
    SSL_METHOD *method = DTLSv1_server_method();
    SSL_CTX *ctx = SSL_CTX_new(method);
    SSL_CTX_load_verify_locations(ctx, "ca-cert.pem", 0);
    SSL_CTX_use_certificate_file(ctx, "server-cert.pem", SSL_FILETYPE_PEM);
    SSL_CTX_use_PrivateKey_file(ctx, "server-key.pem", SSL_FILETYPE_PEM);

    * Client:
    SSL_METHOD *method = DTLSv1_client_method();
    SSL_CTX *ctx = SSL_CTX_new(method);
    SSL_CTX_load_verify_locations(ctx, "ca-cert.pem", 0);

    Do not know what I missed here :(

     
  • Todd Ouska
    Todd Ouska
    2010-08-23

    You don't specify where and when you're calling connect on the server.  connect() on a datagram binds that socket with the peer and keeps CyaSSL from reading data from a different peer.  To disconnect() on a datagram call connect() again by connecting to an invalid address, such as a null address or an address with the address family set to AF_UNSPEC (the error EAFNOSUPPORT will be harmlessly returned).

     
  • aFeLiOn
    aFeLiOn
    2010-08-25

    That makes a lot of sense. i have connect after recvfrom
    Do I need to close server socket, then bind and listen again for each new connection?
    Because if I using udp disconnect:
        struct sockaddr addr;
        addr.sa_family = AF_UNSPEC;
        connect(fd, &addr, 0);
    when client re send another data, it SSL_connect still return SOCKET_ERROR_E.

    I have more question:
    After writing on the socket, client close connection
        SSL_shutdown(ssl);
        close(SSL_get_fd(ssl));
        SSL_free(ssl);
    and the server will be receive a data? because on server, I got SSL accept failed

     
  • aFeLiOn
    aFeLiOn
    2010-08-25

    I also test with your example:
    ./configure -enable-dtls
    ./make
    Run echoserver
    Run echoclient
    type GET -> return OK
    type break
    type quit

    Run echoclient again, got yassl error: SSL_connect failed

     
  • aFeLiOn
    aFeLiOn
    2010-08-25

    Sorry for my annoy, but I can not edit my previous post. Above error just because of SSL_shutdown send notify to server. I just remove it.
    One last question (hopefully): how the server identify clients connected to.
    For example:
    1. Client 1 sends data -> Server accepts
    2. Client 2 sends data -> Server accepts
    3. Client 1 sends another data -> How server know this client and the client at step 1 are identical (same client). For example: client public key?

     
  • Todd Ouska
    Todd Ouska
    2010-08-25

    After you type break on the echoclient you end the session with the server and should do a control-c.  Trying to send a quit or the SSL_shutdown is a problem, I'll fix the echoclient for that case.

    The server can identify the client by the client ip address and client port.

     
  • aFeLiOn
    aFeLiOn
    2010-08-26

    The server can identify the client by the client ip address and client port.

    But connecting port is changed each time a client send data to the server, isn't it?
    The port is selected automatically by OS?

     
  • Todd Ouska
    Todd Ouska
    2010-08-26

    Not if the client connect()s which is about the only way it can guarantee that it's only going to get UDP messages from the correct server during the handshake and data transmission.

    Do you know see why TLS is the better solution here?

     
  • aFeLiOn
    aFeLiOn
    2010-09-09

    As in #8, I said about implementation of my server/client: using select with non blocking socket,
    Both run ok, but if a client sends 5~10 packages in sequence (no delay) the server SSL_accept got error (-208), then can not listen to any clients.
    Do you have any suggestions?