Stuff.
parent
78670e5b71
commit
bbf7e669ff
|
@ -5,6 +5,8 @@ const net = std.net;
|
||||||
const os = std.os;
|
const os = std.os;
|
||||||
const fmt = std.fmt;
|
const fmt = std.fmt;
|
||||||
|
|
||||||
|
const receive_fd = @import("./exchange-fd.zig").receive_fd;
|
||||||
|
|
||||||
const Timer = std.time.Timer;
|
const Timer = std.time.Timer;
|
||||||
|
|
||||||
const print = std.debug.print;
|
const print = std.debug.print;
|
||||||
|
@ -33,10 +35,7 @@ pub const Context = struct {
|
||||||
allocator: std.mem.Allocator, // Memory allocator.
|
allocator: std.mem.Allocator, // Memory allocator.
|
||||||
connections: Connections, // Keep track of connections.
|
connections: Connections, // Keep track of connections.
|
||||||
|
|
||||||
// TODO: List of "pollfd" structures within cinfos,
|
// "pollfd" structures passed to poll(2). Same indexes as "connections".
|
||||||
// so we can pass it to poll(2). Share indexes with 'connections'.
|
|
||||||
// For now, this list doesn't do anything.
|
|
||||||
// Can even be replaced in a near future.
|
|
||||||
pollfd: PollFD, // .fd (fd_t) + .events (i16) + .revents (i16)
|
pollfd: PollFD, // .fd (fd_t) + .events (i16) + .revents (i16)
|
||||||
|
|
||||||
tx: Messages, // Messages to send, once their fd is available.
|
tx: Messages, // Messages to send, once their fd is available.
|
||||||
|
@ -97,14 +96,12 @@ pub const Context = struct {
|
||||||
const newfd = stream.handle;
|
const newfd = stream.handle;
|
||||||
errdefer std.os.closeSocket(newfd);
|
errdefer std.os.closeSocket(newfd);
|
||||||
var newcon = Connection.init(ctype, null);
|
var newcon = Connection.init(ctype, null);
|
||||||
try self.connections.append(newcon);
|
try self.add_ (newcon, newfd);
|
||||||
try self.pollfd.append(.{ .fd = newfd
|
|
||||||
, .events = std.os.linux.POLL.IN
|
|
||||||
, .revents = 0 });
|
|
||||||
return newfd;
|
return newfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connect_ipcd (self: *Self, service_name: []const u8) !?i32 {
|
fn connect_ipcd (self: *Self, service_name: []const u8
|
||||||
|
, connection_type: Connection.Type) !?i32 {
|
||||||
|
|
||||||
const buffer_size = 10000;
|
const buffer_size = 10000;
|
||||||
var buffer: [buffer_size]u8 = undefined;
|
var buffer: [buffer_size]u8 = undefined;
|
||||||
|
@ -138,15 +135,25 @@ pub const Context = struct {
|
||||||
// content: target service name;${IPC_NETWORK}
|
// content: target service name;${IPC_NETWORK}
|
||||||
// example: pong;pong tls://example.com:8998/pong
|
// example: pong;pong tls://example.com:8998/pong
|
||||||
|
|
||||||
var m = try Message.init (ipcdfd, fba, Message.Type.LOOKUP, lookupfbs.getWritten());
|
var m = try Message.init (ipcdfd, Message.Type.LOOKUP, fba, lookupfbs.getWritten());
|
||||||
try self.write (m);
|
try self.write (m);
|
||||||
|
|
||||||
// TODO
|
|
||||||
// var response = something like "try os.recvmsg"
|
|
||||||
// Read LOOKUP response
|
// Read LOOKUP response
|
||||||
// case error: ignore and move on
|
// case error: ignore and move on (TODO)
|
||||||
// else: get fd sent by IPCd then close IPCd fd
|
// else: get fd sent by IPCd then close IPCd fd
|
||||||
|
var newfd = try receive_fd (ipcdfd);
|
||||||
|
var newcon = Connection.init(connection_type, null);
|
||||||
|
try self.add_ (newcon, newfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO: Add a new connection, but takes care of memory problems:
|
||||||
|
/// in case one of the arrays cannot sustain another entry, the other
|
||||||
|
/// won't be added.
|
||||||
|
fn add_ (self: *Self, new_connection: Connection, fd: os.socket_t) !void {
|
||||||
|
try self.connections.append(new_connection);
|
||||||
|
try self.pollfd.append(.{ .fd = fd
|
||||||
|
, .events = std.os.linux.POLL.IN
|
||||||
|
, .revents = 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fd_to_index (self: Self, fd: i32) !usize {
|
fn fd_to_index (self: Self, fd: i32) !usize {
|
||||||
|
@ -200,10 +207,7 @@ pub const Context = struct {
|
||||||
|
|
||||||
const newfd = client.stream.handle;
|
const newfd = client.stream.handle;
|
||||||
var newcon = Connection.init(Connection.Type.IPC, null);
|
var newcon = Connection.init(Connection.Type.IPC, null);
|
||||||
try self.connections.append(newcon);
|
try self.add_ (newcon, newfd);
|
||||||
try self.pollfd.append(.{ .fd = newfd
|
|
||||||
, .events = std.os.linux.POLL.IN
|
|
||||||
, .revents = 0 });
|
|
||||||
|
|
||||||
const sfd = server.sockfd orelse return error.SocketLOL; // TODO
|
const sfd = server.sockfd orelse return error.SocketLOL; // TODO
|
||||||
// WARNING: imply every new item is last
|
// WARNING: imply every new item is last
|
||||||
|
@ -222,10 +226,7 @@ pub const Context = struct {
|
||||||
const newfd = server.sockfd orelse return error.SocketLOL; // TODO
|
const newfd = server.sockfd orelse return error.SocketLOL; // TODO
|
||||||
// Store the path in the Connection structure, so the UNIX socket file can be removed later.
|
// Store the path in the Connection structure, so the UNIX socket file can be removed later.
|
||||||
var newcon = Connection.init(Connection.Type.SERVER, try self.allocator.dupeZ(u8, path));
|
var newcon = Connection.init(Connection.Type.SERVER, try self.allocator.dupeZ(u8, path));
|
||||||
try self.connections.append(newcon);
|
try self.add_ (newcon, newfd);
|
||||||
try self.pollfd.append(.{ .fd = newfd
|
|
||||||
, .events = std.os.linux.POLL.IN
|
|
||||||
, .revents = 0 });
|
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,8 @@ test {
|
||||||
std.testing.refAllDecls(Cmsghdr([3]std.os.fd_t));
|
std.testing.refAllDecls(Cmsghdr([3]std.os.fd_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Send a file descriptor and a message through a UNIX socket.
|
||||||
|
/// TODO: currently voluntarily crashes if data isn't sent properly, should return an error instead.
|
||||||
pub fn send_fd(sockfd: os.socket_t, msg: []const u8, fd: os.fd_t) void {
|
pub fn send_fd(sockfd: os.socket_t, msg: []const u8, fd: os.fd_t) void {
|
||||||
var iov = [_]os.iovec_const{
|
var iov = [_]os.iovec_const{
|
||||||
.{
|
.{
|
||||||
|
@ -107,7 +109,9 @@ pub fn send_fd(sockfd: os.socket_t, msg: []const u8, fd: os.fd_t) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: errors aren't RECEPTION errors.
|
/// WARNING: recvmsg is a WIP.
|
||||||
|
/// WARNING: errors aren't RECEPTION errors.
|
||||||
|
/// WARNING: can only work on linux for now (recvmsg is lacking on other systems).
|
||||||
pub fn recvmsg(
|
pub fn recvmsg(
|
||||||
/// The file descriptor of the sending socket.
|
/// The file descriptor of the sending socket.
|
||||||
sockfd: os.socket_t,
|
sockfd: os.socket_t,
|
||||||
|
@ -180,13 +184,17 @@ pub fn recvmsg(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn receive_fd(sockfd: os.socket_t) !os.fd_t {
|
/// Receive a file descriptor through a UNIX socket.
|
||||||
var buffer: [100]u8 = undefined;
|
/// A message can be carried with it, copied into 'buffer'.
|
||||||
|
/// WARNING: buffer must be at least 1500 bytes.
|
||||||
|
pub fn receive_fd(sockfd: os.socket_t, buffer: []u8, msg_size: *usize) !os.fd_t {
|
||||||
|
|
||||||
|
var msg_buffer: [1500]u8 = undefined;
|
||||||
|
|
||||||
var iov = [1]os.iovec{
|
var iov = [1]os.iovec{
|
||||||
.{
|
.{
|
||||||
.iov_base = buffer[0..],
|
.iov_base = msg_buffer[0..]
|
||||||
.iov_len = buffer.len,
|
, .iov_len = buffer.len
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -204,14 +212,17 @@ pub fn receive_fd(sockfd: os.socket_t) !os.fd_t {
|
||||||
.control = &cmsg,
|
.control = &cmsg,
|
||||||
.controllen = @sizeOf(@TypeOf(cmsg)),
|
.controllen = @sizeOf(@TypeOf(cmsg)),
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const len = recvmsg(sockfd, msg, 0) catch |err| {
|
_ = recvmsg(sockfd, msg, 0) catch |err| {
|
||||||
print("error sendmsg failed with {s}", .{@errorName(err)});
|
print("error sendmsg failed with {s}", .{@errorName(err)});
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
print("received {} bytes, fd is {}\n", .{len, @as(i32, cmsg.dataPtr().*)});
|
var received_fd = @as(i32, cmsg.dataPtr().*);
|
||||||
print("iov base {s}\n", .{iov[0].iov_base[0..iov[0].iov_len - 1]});
|
// print("received {} bytes, fd is {}\n", .{len, received_fd});
|
||||||
return @as(i32, cmsg.dataPtr().*);
|
// print("payload (iov base) {s}\n", .{iov[0].iov_base[0..iov[0].iov_len - 1]});
|
||||||
|
std.mem.copy(u8, buffer, &msg_buffer);
|
||||||
|
msg_size.* = iov[0].iov_len;
|
||||||
|
return received_fd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,11 @@ const fmt = std.fmt;
|
||||||
const os = std.os;
|
const os = std.os;
|
||||||
|
|
||||||
const ipc = @import("./main.zig");
|
const ipc = @import("./main.zig");
|
||||||
|
const Message = ipc.Message;
|
||||||
|
|
||||||
|
// Import send_fd this way in order to produce docs for exchange-fd functions.
|
||||||
|
const exchange_fd = @import("./exchange-fd.zig");
|
||||||
|
const send_fd = exchange_fd.send_fd;
|
||||||
|
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const native_os = builtin.target.os.tag;
|
const native_os = builtin.target.os.tag;
|
||||||
|
@ -111,8 +116,33 @@ fn create_service() !void {
|
||||||
|
|
||||||
.LOOKUP => {
|
.LOOKUP => {
|
||||||
print("Client asking for a service through ipcd.\n", .{});
|
print("Client asking for a service through ipcd.\n", .{});
|
||||||
print("NOT IMPLEMENTED, YET. It's a suicide, then.\n", .{});
|
if (some_event.m) |m| {
|
||||||
break;
|
print("Message: {}\n", .{m});
|
||||||
|
// 1. split message
|
||||||
|
// TODO
|
||||||
|
print("payload is: {s}\n", .{m.payload});
|
||||||
|
// 2. find relevant part of the message
|
||||||
|
// TODO
|
||||||
|
// 3. connect whether asked to
|
||||||
|
// TODO
|
||||||
|
// 4. send_fd or send an error
|
||||||
|
// TODO
|
||||||
|
var response = try Message.init(some_event.origin
|
||||||
|
, Message.Type.ERROR
|
||||||
|
, allocator
|
||||||
|
, "currently not implemented");
|
||||||
|
try ctx.write(response);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// There is a problem: ipcd was contacted without providing
|
||||||
|
// a message, meaning there is nothing to do. This should be
|
||||||
|
// explicitely warned about.
|
||||||
|
var m = try Message.init(some_event.origin
|
||||||
|
, Message.Type.ERROR
|
||||||
|
, allocator
|
||||||
|
, "lookup message without data");
|
||||||
|
try ctx.write(m);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
.TX => {
|
.TX => {
|
||||||
|
|
Reference in New Issue