From: Alan T. DeKok Date: Tue, 23 Jan 2024 13:51:44 +0000 (-0500) Subject: add support for file IO in bios X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cbab7f4f8b29256fd13042d0ec4c503737b413c1;p=thirdparty%2Ffreeradius-server.git add support for file IO in bios --- diff --git a/src/lib/bio/fd.c b/src/lib/bio/fd.c index 3707d5409d4..ab22527083e 100644 --- a/src/lib/bio/fd.c +++ b/src/lib/bio/fd.c @@ -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 diff --git a/src/lib/bio/fd.h b/src/lib/bio/fd.h index 933a0cb0f29..c175851c59c 100644 --- a/src/lib/bio/fd.h +++ b/src/lib/bio/fd.h @@ -29,6 +29,13 @@ RCSIDH(lib_bio_fd_h, "$Id$") #include #include +#include + +/* + * 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); diff --git a/src/lib/bio/fd_open.c b/src/lib/bio/fd_open.c index 1fc1b5c4015..59b82bcea88 100644 --- a/src/lib/bio/fd_open.c +++ b/src/lib/bio/fd_open.c @@ -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; + } } /*