From 5858824b20871a0b43f1c700fed4221a1a0482a3 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Tue, 4 Jun 2024 00:27:35 +0100 Subject: [PATCH] support unix socket addresses in listen and connect --- src/config.rs | 18 +++++++++++++----- src/ext.rs | 12 +++++++----- src/proxy.rs | 10 ++++++---- src/server.rs | 10 ++++++---- src/socketwrapper.rs | 2 +- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/config.rs b/src/config.rs index 9f7f463..596edea 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,7 @@ use std::collections::BTreeSet; use std::fs; use std::net::{IpAddr, Ipv4Addr}; +use std::path::PathBuf; use anyhow::{Context, Result}; use directories::ProjectDirs; @@ -21,12 +22,12 @@ mod default { 10 } - pub fn listen() -> (IpAddr, u16) { + pub fn listen() -> ListenAddr { // localhost & some random unprivileged port - (IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 27_631) + ListenAddr::Tcp(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 27_631) } - pub fn connect() -> (IpAddr, u16) { + pub fn connect() -> ListenAddr { listen() } @@ -82,6 +83,13 @@ mod de { } } +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum ListenAddr { + Tcp(IpAddr, u16), + Unix(PathBuf), +} + #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct Config { @@ -94,10 +102,10 @@ pub struct Config { pub gc_interval: u32, #[serde(default = "default::listen")] - pub listen: (IpAddr, u16), + pub listen: ListenAddr, #[serde(default = "default::connect")] - pub connect: (IpAddr, u16), + pub connect: ListenAddr, #[serde(default = "default::log_filters")] pub log_filters: String, diff --git a/src/ext.rs b/src/ext.rs index 0089123..7d2ab26 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -4,7 +4,7 @@ use anyhow::{bail, Context, Result}; use serde::de::{DeserializeOwned, IgnoredAny}; use tokio::io::BufReader; -use crate::config::Config; +use crate::config::{Config, ListenAddr}; use crate::lsp::ext::{self, LspMuxOptions, StatusResponse}; use crate::lsp::jsonrpc::{Message, Request, RequestId, Version}; use crate::lsp::transport::{LspReader, LspWriter}; @@ -15,10 +15,12 @@ pub async fn ext_request(config: &Config, method: ext::Request) -> Result where T: DeserializeOwned, { - let (reader, writer) = Stream::connect_tcp(config.connect) - .await - .context("connect")? - .into_split(); + let (reader, writer) = match config.connect { + ListenAddr::Tcp(ip_addr, port) => Stream::connect_tcp((ip_addr, port)).await, + ListenAddr::Unix(ref path) => Stream::connect_unix(path).await, + } + .context("connect")? + .into_split(); let mut writer = LspWriter::new(writer, "lspmux"); let mut reader = LspReader::new(BufReader::new(reader), "lspmux"); diff --git a/src/proxy.rs b/src/proxy.rs index 13dd35a..d7fc190 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -4,7 +4,7 @@ use std::env; use anyhow::{bail, Context as _, Result}; use tokio::io::{self, BufStream}; -use crate::config::Config; +use crate::config::{Config, ListenAddr}; use crate::lsp::ext::{LspMuxOptions, Request}; use crate::lsp::jsonrpc::Message; use crate::lsp::transport::{LspReader, LspWriter}; @@ -23,9 +23,11 @@ pub async fn run(config: &Config, server: String, args: Vec) -> Result<( } } - let mut stream = Stream::connect_tcp(config.connect) - .await - .context("connect")?; + let mut stream = match config.connect { + ListenAddr::Tcp(ip_addr, port) => Stream::connect_tcp((ip_addr, port)).await, + ListenAddr::Unix(ref path) => Stream::connect_unix(path).await, + } + .context("connect")?; let mut stdio = BufStream::new(io::join(io::stdin(), io::stdout())); // Wait for the client to send `initialize` request. diff --git a/src/server.rs b/src/server.rs index c5a9ae0..c8889ea 100644 --- a/src/server.rs +++ b/src/server.rs @@ -5,7 +5,7 @@ use tokio::task; use tracing::{error, info, info_span, warn, Instrument}; use crate::client; -use crate::config::Config; +use crate::config::{Config, ListenAddr}; use crate::instance::InstanceMap; use crate::socketwrapper::Listener; @@ -13,9 +13,11 @@ pub async fn run(config: &Config) -> Result<()> { let instance_map = InstanceMap::new(config).await; let next_client_id = AtomicUsize::new(0); - let listener = Listener::bind_tcp(config.listen.into()) - .await - .context("listen")?; + let listener = match config.listen { + ListenAddr::Tcp(ip_addr, port) => Listener::bind_tcp((ip_addr, port).into()).await, + ListenAddr::Unix(ref path) => Listener::bind_unix(path), + } + .context("listen")?; loop { match listener.accept().await { Ok((socket, _addr)) => { diff --git a/src/socketwrapper.rs b/src/socketwrapper.rs index d3d6e9f..47bf560 100644 --- a/src/socketwrapper.rs +++ b/src/socketwrapper.rs @@ -1,7 +1,7 @@ use std::path::Path; use std::pin::Pin; use std::task::{Context, Poll}; -use std::{io, net}; +use std::{fs, io, net}; use pin_project::pin_project; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};