]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add support for file IO in bios
authorAlan T. DeKok <aland@freeradius.org>
Tue, 23 Jan 2024 13:51:44 +0000 (08:51 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 23 Jan 2024 13:51:44 +0000 (08:51 -0500)
src/lib/bio/fd.c
src/lib/bio/fd.h
src/lib/bio/fd_open.c

index 3707d5409d46a802c40617324412c9298ad3b206..ab22527083e025e6e0acda442f045acbae660589 100644 (file)
@@ -712,8 +712,44 @@ fail:
         return fr_bio_error(IO);
 }
 
+/** Files are a special case of connected sockets.
+ *
+ */
+static int fr_bio_fd_init_file(fr_bio_fd_t *my)
+{
+       my->info.state = FR_BIO_FD_STATE_OPEN;
+       my->info.eof = false;
+       my->info.read_blocked = false;
+       my->info.write_blocked = false;
+
+       switch (my->info.cfg->flags) {
+       case O_RDONLY:
+               my->bio.read = fr_bio_fd_read_stream;
+               my->bio.write = fr_bio_null_write; /* @todo - error on write? */
+               break;
+
+       case O_WRONLY:
+               my->bio.read = fr_bio_null_read; /* @todo - error on read? */
+               my->bio.write = fr_bio_fd_write;
+               break;
+
+       case O_RDWR:
+               my->bio.read = fr_bio_fd_read_stream;
+               my->bio.write = fr_bio_fd_write;
+               break;
+
+       default:
+               fr_strerror_const("Invalid flag for opening file");
+               return -1;
+       }
+
+       return 0;
+}
+
 int fr_bio_fd_init_connected(fr_bio_fd_t *my)
 {
+       if (my->info.socket.af == AF_FILE) return fr_bio_fd_init_file(my);
+
        /*
         *      Connected datagrams must have real IPs
         */
@@ -891,7 +927,6 @@ int fr_bio_fd_init_accept(fr_bio_fd_t *my)
        return 0;
 }
 
-
 /** Allocate a FD bio
  *
  *  The caller is responsible for tracking the FD, and all associated management of it.  The bio API is
@@ -957,7 +992,7 @@ fr_bio_t *fr_bio_fd_alloc(TALLOC_CTX *ctx, fr_bio_cb_funcs_t *cb, fr_bio_fd_conf
        } else {
                my->info.state = FR_BIO_FD_STATE_CLOSED;
 
-               if (fr_bio_fd_socket_open(&my->bio, cfg) < 0) {
+               if (fr_bio_fd_open(&my->bio, cfg) < 0) {
                        talloc_free(my);
                        return NULL;
                }
@@ -1028,35 +1063,6 @@ retry:
        return 0;
 }
 
-/** re-open the bio
- */
-int fr_bio_fd_init(fr_bio_t *bio, fr_socket_t const *sock)
-{
-       fr_bio_fd_t *my = talloc_get_type_abort(bio, fr_bio_fd_t);
-
-       fr_assert(my->info.socket.inet.src_ipaddr.af == my->info.socket.inet.dst_ipaddr.af);
-
-       /*
-        *      The bio can't be open if we're re-initializing it.
-        */
-       if (my->info.state == FR_BIO_FD_STATE_OPEN) return -1;
-
-       my->info.socket = *sock;
-
-       switch (my->info.type) {
-       case FR_BIO_FD_UNCONNECTED:
-               return fr_bio_fd_init_common(my);
-
-       case FR_BIO_FD_CONNECTED:
-               return fr_bio_fd_init_connected(my);
-
-       case FR_BIO_FD_ACCEPT:
-               return fr_bio_fd_init_accept(my);
-       }
-
-       return -1;
-}
-
 /** Finalize a connect()
  *
  *  connect() said "come back when the socket is writeable".  It's now writeable, so we check if there was a
index 933a0cb0f291606c601f40ba3e9f6d8e784f3bb2..c175851c59c1f00cd6ac0ad5e2a146a99199c1e7 100644 (file)
@@ -29,6 +29,13 @@ RCSIDH(lib_bio_fd_h, "$Id$")
 #include <freeradius-devel/bio/base.h>
 #include <freeradius-devel/util/socket.h>
 
+#include <fcntl.h>
+
+/*
+ *     Local hack.
+ */
+#define AF_FILE (INT_MAX)
+
 /** Per-packet context
  *
  *     For reading packets src_ip is *their* IP, and dst_ip is *our* IP.
@@ -87,6 +94,9 @@ typedef struct {
        uid_t           uid;            //!< who owns the socket
        gid_t           gid;            //!< who owns the socket
 
+       char const      *filename;      //!< for files
+       int             flags;          //!< O_RDONLY, etc.
+
        bool            async;          //!< is it async
 } fr_bio_fd_config_t;
 
@@ -111,12 +121,10 @@ fr_bio_t  *fr_bio_fd_alloc(TALLOC_CTX *ctx, fr_bio_cb_funcs_t *cb, fr_bio_fd_conf
 
 int            fr_bio_fd_close(fr_bio_t *bio) CC_HINT(nonnull);
 
-int            fr_bio_fd_init(fr_bio_t *bio, fr_socket_t const *sock) CC_HINT(nonnull);
-
 int            fr_bio_fd_connect(fr_bio_t *bio) CC_HINT(nonnull);
 
 fr_bio_fd_info_t const *fr_bio_fd_info(fr_bio_t *bio) CC_HINT(nonnull);
 
-int            fr_bio_fd_socket_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg) CC_HINT(nonnull);
+int            fr_bio_fd_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg) CC_HINT(nonnull);
 
 int            fr_bio_fd_write_only(fr_bio_t *bio);
index 1fc1b5c401586a50ff954e4151c867553bdb36ff..59b82bcea8879e4eaa593cfc93fb65a91e4f1e66 100644 (file)
@@ -711,9 +711,9 @@ static int fr_bio_fd_socket_bind(fr_bio_fd_t *my, fr_bio_fd_config_t const *cfg)
  *
  *  Note that it does not call connect()!
  */
-int fr_bio_fd_socket_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg)
+int fr_bio_fd_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg)
 {
-       int fd, protocol;
+       int fd;
        int rcode;
        fr_bio_fd_t *my = talloc_get_type_abort(bio, fr_bio_fd_t);
 
@@ -726,7 +726,9 @@ int fr_bio_fd_socket_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg)
                .cfg = cfg,
        };
 
-       if (!cfg->path) {
+       if (!cfg->path && !cfg->filename) {
+               int protocol;
+
                my->info.socket.af = cfg->src_ipaddr.af;
                my->info.socket.inet.src_ipaddr = cfg->src_ipaddr;
                my->info.socket.inet.dst_ipaddr = cfg->dst_ipaddr;
@@ -747,20 +749,37 @@ int fr_bio_fd_socket_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg)
                                return -1;
                        }
                }
-       } else {
-               my->info.socket.af = AF_UNIX;
+
+               fd = socket(my->info.socket.af, my->info.socket.type, protocol);
+               if (fd < 0) {
+                       fr_strerror_printf("Failed opening socket: %s", fr_syserror(errno));
+                       return -1;
+               }
+
+       } else if (cfg->path) {
+               my->info.socket.af = AF_LOCAL;
                my->info.socket.type = SOCK_STREAM;
                my->info.socket.unix.path = cfg->path;
-               protocol = 0;
-       }
 
-       /*
-        *      Open the socket.
-        */
-       fd = socket(my->info.socket.af, my->info.socket.type, protocol);
-       if (fd < 0) {
-               fr_strerror_printf("Failed opening socket: %s", fr_syserror(errno));
-               return -1;
+               fd = socket(my->info.socket.af, my->info.socket.type, 0);
+               if (fd < 0) {
+                       fr_strerror_printf("Failed opening domain socket %s: %s", cfg->path, fr_syserror(errno));
+                       return -1;
+               }
+
+       } else {
+               /*
+                *      Filenames overload the #fr_socket_t for now.
+                */
+               my->info.socket.af = AF_FILE;
+               my->info.socket.type = SOCK_STREAM;
+               my->info.socket.unix.path = cfg->filename;
+
+               fd = open(cfg->filename, cfg->flags);
+               if (fd < 0) {
+                       fr_strerror_printf("Failed opening file %s: %s", cfg->filename, fr_syserror(errno));
+                       return -1;
+               }
        }
 
        /*