|
|
@ -188,6 +188,7 @@ impl ServerHandler for ManagerServer {
|
|
|
|
type Response = ManagerResponse;
|
|
|
|
type Response = ManagerResponse;
|
|
|
|
|
|
|
|
|
|
|
|
async fn on_request(&self, ctx: RequestCtx<Self::Request, Self::Response>) {
|
|
|
|
async fn on_request(&self, ctx: RequestCtx<Self::Request, Self::Response>) {
|
|
|
|
|
|
|
|
debug!("manager::on_request({ctx:?})");
|
|
|
|
let RequestCtx {
|
|
|
|
let RequestCtx {
|
|
|
|
connection_id,
|
|
|
|
connection_id,
|
|
|
|
request,
|
|
|
|
request,
|
|
|
@ -195,113 +196,161 @@ impl ServerHandler for ManagerServer {
|
|
|
|
} = ctx;
|
|
|
|
} = ctx;
|
|
|
|
|
|
|
|
|
|
|
|
let response = match request.payload {
|
|
|
|
let response = match request.payload {
|
|
|
|
ManagerRequest::Capabilities {} => match self.capabilities().await {
|
|
|
|
ManagerRequest::Capabilities {} => {
|
|
|
|
Ok(supported) => ManagerResponse::Capabilities { supported },
|
|
|
|
debug!("Looking up capabilities");
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
match self.capabilities().await {
|
|
|
|
},
|
|
|
|
Ok(supported) => ManagerResponse::Capabilities { supported },
|
|
|
|
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
ManagerRequest::Launch {
|
|
|
|
ManagerRequest::Launch {
|
|
|
|
destination,
|
|
|
|
destination,
|
|
|
|
options,
|
|
|
|
options,
|
|
|
|
} => match self
|
|
|
|
} => {
|
|
|
|
.launch(
|
|
|
|
info!("Launching {destination} with {options}");
|
|
|
|
*destination,
|
|
|
|
match self
|
|
|
|
options,
|
|
|
|
.launch(
|
|
|
|
ManagerAuthenticator {
|
|
|
|
*destination,
|
|
|
|
reply: reply.clone(),
|
|
|
|
options,
|
|
|
|
registry: Arc::clone(&self.registry),
|
|
|
|
ManagerAuthenticator {
|
|
|
|
},
|
|
|
|
reply: reply.clone(),
|
|
|
|
)
|
|
|
|
registry: Arc::clone(&self.registry),
|
|
|
|
.await
|
|
|
|
},
|
|
|
|
{
|
|
|
|
)
|
|
|
|
Ok(destination) => ManagerResponse::Launched { destination },
|
|
|
|
.await
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
{
|
|
|
|
},
|
|
|
|
Ok(destination) => ManagerResponse::Launched { destination },
|
|
|
|
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
ManagerRequest::Connect {
|
|
|
|
ManagerRequest::Connect {
|
|
|
|
destination,
|
|
|
|
destination,
|
|
|
|
options,
|
|
|
|
options,
|
|
|
|
} => match self
|
|
|
|
} => {
|
|
|
|
.connect(
|
|
|
|
info!("Connecting to {destination} with {options}");
|
|
|
|
*destination,
|
|
|
|
match self
|
|
|
|
options,
|
|
|
|
.connect(
|
|
|
|
ManagerAuthenticator {
|
|
|
|
*destination,
|
|
|
|
reply: reply.clone(),
|
|
|
|
options,
|
|
|
|
registry: Arc::clone(&self.registry),
|
|
|
|
ManagerAuthenticator {
|
|
|
|
},
|
|
|
|
reply: reply.clone(),
|
|
|
|
)
|
|
|
|
registry: Arc::clone(&self.registry),
|
|
|
|
.await
|
|
|
|
},
|
|
|
|
{
|
|
|
|
)
|
|
|
|
Ok(id) => ManagerResponse::Connected { id },
|
|
|
|
.await
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
{
|
|
|
|
},
|
|
|
|
Ok(id) => ManagerResponse::Connected { id },
|
|
|
|
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
ManagerRequest::Authenticate { id, msg } => {
|
|
|
|
ManagerRequest::Authenticate { id, msg } => {
|
|
|
|
|
|
|
|
trace!("Retrieving authentication callback registry");
|
|
|
|
match self.registry.write().await.remove(&id) {
|
|
|
|
match self.registry.write().await.remove(&id) {
|
|
|
|
Some(cb) => match cb.send(msg) {
|
|
|
|
Some(cb) => {
|
|
|
|
Ok(_) => return,
|
|
|
|
trace!("Sending {msg:?} through authentication callback");
|
|
|
|
Err(_) => ManagerResponse::Error {
|
|
|
|
match cb.send(msg) {
|
|
|
|
description: "Unable to forward authentication callback".to_string(),
|
|
|
|
Ok(_) => return,
|
|
|
|
},
|
|
|
|
Err(_) => ManagerResponse::Error {
|
|
|
|
},
|
|
|
|
description: "Unable to forward authentication callback"
|
|
|
|
|
|
|
|
.to_string(),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
None => ManagerResponse::from(io::Error::new(
|
|
|
|
None => ManagerResponse::from(io::Error::new(
|
|
|
|
io::ErrorKind::InvalidInput,
|
|
|
|
io::ErrorKind::InvalidInput,
|
|
|
|
"Invalid authentication id",
|
|
|
|
"Invalid authentication id",
|
|
|
|
)),
|
|
|
|
)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ManagerRequest::OpenChannel { id } => match self.connections.read().await.get(&id) {
|
|
|
|
ManagerRequest::OpenChannel { id } => {
|
|
|
|
Some(connection) => match connection.open_channel(reply.clone()) {
|
|
|
|
debug!("Attempting to retrieve connection {id}");
|
|
|
|
Ok(channel) => {
|
|
|
|
match self.connections.read().await.get(&id) {
|
|
|
|
debug!("[Conn {id}] Channel {} has been opened", channel.id());
|
|
|
|
Some(connection) => {
|
|
|
|
let id = channel.id();
|
|
|
|
debug!("Opening channel through connection {id}");
|
|
|
|
self.channels.write().await.insert(id, channel);
|
|
|
|
match connection.open_channel(reply.clone()) {
|
|
|
|
ManagerResponse::ChannelOpened { id }
|
|
|
|
Ok(channel) => {
|
|
|
|
|
|
|
|
info!("[Conn {id}] Channel {} has been opened", channel.id());
|
|
|
|
|
|
|
|
let id = channel.id();
|
|
|
|
|
|
|
|
self.channels.write().await.insert(id, channel);
|
|
|
|
|
|
|
|
ManagerResponse::ChannelOpened { id }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
None => ManagerResponse::from(io::Error::new(
|
|
|
|
},
|
|
|
|
io::ErrorKind::NotConnected,
|
|
|
|
None => ManagerResponse::from(io::Error::new(
|
|
|
|
"Connection does not exist",
|
|
|
|
io::ErrorKind::NotConnected,
|
|
|
|
)),
|
|
|
|
"Connection does not exist",
|
|
|
|
}
|
|
|
|
)),
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
ManagerRequest::Channel { id, request } => {
|
|
|
|
ManagerRequest::Channel { id, request } => {
|
|
|
|
|
|
|
|
debug!("Attempting to retrieve channel {id}");
|
|
|
|
match self.channels.read().await.get(&id) {
|
|
|
|
match self.channels.read().await.get(&id) {
|
|
|
|
// TODO: For now, we are NOT sending back a response to acknowledge
|
|
|
|
// TODO: For now, we are NOT sending back a response to acknowledge
|
|
|
|
// a successful channel send. We could do this in order for
|
|
|
|
// a successful channel send. We could do this in order for
|
|
|
|
// the client to listen for a complete send, but is it worth it?
|
|
|
|
// the client to listen for a complete send, but is it worth it?
|
|
|
|
Some(channel) => match channel.send(request) {
|
|
|
|
Some(channel) => {
|
|
|
|
Ok(_) => return,
|
|
|
|
debug!("Sending {request:?} through channel {id}");
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
match channel.send(request) {
|
|
|
|
},
|
|
|
|
Ok(_) => return,
|
|
|
|
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
None => ManagerResponse::from(io::Error::new(
|
|
|
|
|
|
|
|
io::ErrorKind::NotConnected,
|
|
|
|
|
|
|
|
"Channel is not open or does not exist",
|
|
|
|
|
|
|
|
)),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ManagerRequest::CloseChannel { id } => {
|
|
|
|
|
|
|
|
debug!("Attempting to remove channel {id}");
|
|
|
|
|
|
|
|
match self.channels.write().await.remove(&id) {
|
|
|
|
|
|
|
|
Some(channel) => {
|
|
|
|
|
|
|
|
debug!("Removed channel {}", channel.id());
|
|
|
|
|
|
|
|
match channel.close() {
|
|
|
|
|
|
|
|
Ok(_) => {
|
|
|
|
|
|
|
|
info!("Channel {id} has been closed");
|
|
|
|
|
|
|
|
ManagerResponse::ChannelClosed { id }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
None => ManagerResponse::from(io::Error::new(
|
|
|
|
None => ManagerResponse::from(io::Error::new(
|
|
|
|
io::ErrorKind::NotConnected,
|
|
|
|
io::ErrorKind::NotConnected,
|
|
|
|
"Channel is not open or does not exist",
|
|
|
|
"Channel is not open or does not exist",
|
|
|
|
)),
|
|
|
|
)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ManagerRequest::CloseChannel { id } => match self.channels.write().await.remove(&id) {
|
|
|
|
ManagerRequest::Info { id } => {
|
|
|
|
Some(channel) => match channel.close() {
|
|
|
|
debug!("Attempting to retrieve information for connection {id}");
|
|
|
|
Ok(_) => {
|
|
|
|
match self.info(id).await {
|
|
|
|
debug!("Channel {id} has been closed");
|
|
|
|
Ok(info) => {
|
|
|
|
ManagerResponse::ChannelClosed { id }
|
|
|
|
info!("Retrieved information for connection {id}");
|
|
|
|
|
|
|
|
ManagerResponse::Info(info)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
None => ManagerResponse::from(io::Error::new(
|
|
|
|
}
|
|
|
|
io::ErrorKind::NotConnected,
|
|
|
|
ManagerRequest::List => {
|
|
|
|
"Channel is not open or does not exist",
|
|
|
|
debug!("Attempting to retrieve the list of connections");
|
|
|
|
)),
|
|
|
|
match self.list().await {
|
|
|
|
},
|
|
|
|
Ok(list) => {
|
|
|
|
ManagerRequest::Info { id } => match self.info(id).await {
|
|
|
|
info!("Retrieved list of connections");
|
|
|
|
Ok(info) => ManagerResponse::Info(info),
|
|
|
|
ManagerResponse::List(list)
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
ManagerRequest::List => match self.list().await {
|
|
|
|
}
|
|
|
|
Ok(list) => ManagerResponse::List(list),
|
|
|
|
}
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
ManagerRequest::Kill { id } => {
|
|
|
|
},
|
|
|
|
debug!("Attempting to kill connection {id}");
|
|
|
|
ManagerRequest::Kill { id } => match self.kill(id).await {
|
|
|
|
match self.kill(id).await {
|
|
|
|
Ok(()) => ManagerResponse::Killed,
|
|
|
|
Ok(()) => {
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
info!("Killed connection {id}");
|
|
|
|
},
|
|
|
|
ManagerResponse::Killed
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Err(x) => ManagerResponse::from(x),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if let Err(x) = reply.send(response).await {
|
|
|
|
if let Err(x) = reply.send(response).await {
|
|
|
|