]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
write all of the TLS data as one big blob
authorAlan T. DeKok <aland@freeradius.org>
Sun, 16 Oct 2022 13:12:06 +0000 (09:12 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 16 Oct 2022 13:12:06 +0000 (09:12 -0400)
src/main/tls_listen.c

index 83856c6159c4ffad14eec15d6ce7b7e20052d748..c54342950234bb41bd43ac09e780ea55569e3643 100644 (file)
@@ -95,28 +95,39 @@ static void tls_socket_close(rad_listen_t *listener)
 
 static int CC_HINT(nonnull) tls_socket_write(rad_listen_t *listener, REQUEST *request)
 {
-       uint8_t *p;
        ssize_t rcode;
        listen_socket_t *sock = listener->data;
 
-       p = sock->ssn->dirty_out.data;
+       /*
+        *      Write as much as possible.
+        */
+       RDEBUG3("(TLS) Writing to socket %d", listener->fd);
+       rcode = write(listener->fd, sock->ssn->dirty_out.data, sock->ssn->dirty_out.used);
+       if (rcode <= 0) {
+               RDEBUG("(TLS) Error writing to socket: %s", fr_syserror(errno));
 
-       while (p < (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used)) {
-               RDEBUG3("(TLS) Writing to socket %d", listener->fd);
-               rcode = write(listener->fd, p,
-                             (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used) - p);
-               if (rcode <= 0) {
-                       RDEBUG("(TLS) Error writing to socket: %s", fr_syserror(errno));
+               tls_socket_close(listener);
+               return -1;
+       }
 
-                       tls_socket_close(listener);
-                       return 0;
-               }
-               p += rcode;
+       /*
+        *      All of the data was written.  It's fine.
+        */
+       if ((size_t) rcode == sock->ssn->dirty_out.used) {
+               sock->ssn->dirty_out.used = 0;
+               return 0;
        }
 
-       sock->ssn->dirty_out.used = 0;
+       /*
+        *      Move the data to the start of the buffer.
+        *
+        *      Yes, this is horrible.  But doing this means that we
+        *      don't have to modify the rest of the code which mangles dirty_out, and assumes that the write offset is always &data[used].
+        */
+       memmove(&sock->ssn->dirty_out.data[0], &sock->ssn->dirty_out.data[rcode], sock->ssn->dirty_out.used - rcode);
+       sock->ssn->dirty_out.used -= rcode;
 
-       return 1;
+       return 0;
 }
 
 /*