-
Notifications
You must be signed in to change notification settings - Fork 19
[WIP] Add initial implementation for netcat #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
Arcterus
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only commented on repeated issues once, so several occur more than once.
| extern crate libc; | ||
| extern crate socket2; | ||
|
|
||
| use std; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need to include this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/networking/nc/mod.rs
Outdated
| use mio::{Events, Event, Poll, Ready, PollOpt, Token}; | ||
| use libc::{AF_UNSPEC, AF_INET, AF_INET6, AF_UNIX}; | ||
| use std::io; | ||
| use std::net::{SocketAddr}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there's only one member that you are trying to use from a module, usually you'd just do use std::net::SocketAddr instead of use std::net::{SocketAddr}.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/networking/nc/mod.rs
Outdated
| )) | ||
| } | ||
|
|
||
| fn build_ports(ports: &str) -> Result<Vec<u16>, MesaError>{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you include super::Result, you should be able to just do Result<Vec<u16>>. You could also just do super::Result<Vec<u16>>.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there are not just one type of Result, I think it's better to keep all the Result consistent and make Ok and Err explicit.
src/networking/nc/mod.rs
Outdated
| let port_list = match ports.parse::<u16>() { | ||
| Ok(port) => port, | ||
| Err(_) => { | ||
| return mesaerr_result(&format!("invalid port[s] {}", ports)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that you should create a type like the following rather than using mesaerr_result() everywhere:
use std::num::ParseIntError;
#[derive(Debug, Fail)]
enum NcError {
#[fail(display = "invalid port(s) {}: {}", ports, err)]
ParsePort {
#[cause] err: ParseIntError,
ports: String,
},
// more errors go here
}You can then change this function to something like:
fn build_ports(ports: &str) -> super::Result<Vec<u16>> {
ports
.parse::<u16>()
.map(|port| vec![port])
.map_err(|e| NcError::ParsePort { err: e, ports: ports.to_string() })
}| Ok(vec!(port_list)) | ||
| } | ||
|
|
||
| fn warn(msg: &str) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be fine if the utility was written normally (i.e. as a standalone binary), but because mesabox can be included into other projects as a library, we need to be able to write to custom stdin/stdout/stderr (as in, we need to be able to write to a Vec<u8> or perhaps to a File rather than Stderr). This issue is primarily what UtilSetup is meant to solve. This function should instead be:
fn warn<S: UtilSetup>(setup: &mut S, msg: &str) {
let _ = write!(setup.error(), "{}", msg);
}I haven't fully checked where you use warn() (so what I'm about to say may not fully apply), but there is also display_msg!(), which prints the name of the utility + whatever you want to write to the given output stream (e.g. display_msg!(setup.error(), "{}", msg)).
I probably need to document the structure of the framework somewhere to avoid this sort of confusion.
src/networking/nc/mod.rs
Outdated
| s_addr.clone().unwrap() | ||
| } else { | ||
| let nf = NamedTempFile::new()?; | ||
| let path = String::from(nf.path().to_str().unwrap()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than a String, this should most likely be a Path or PathBuf. You might be able to get Path to work by giving NcOptions a lifetime and not taking ownership of ArgMatches (i.e. use &mut ArgMatches instead).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path won't work since nc doesn't only work for unix. For TCP/UDP, the type is not path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn’t unix_dg_tmp_socket just used for Unix sockets though? I scanned through the code briefly and didn’t notice anything that indicated otherwise, but let me know if I missed something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes unix_dg_tmp_socket is only for unix socket. However, after I changed it to Path, I found that I had to immediately convert it to string because the functions consuming it also handle TCP/UDP and cannot take Path. Besides, no Path-related action is performed so there is no benefit to use Path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What exactly requires conversion into a string? I believe I have this working fine using Paths locally (although to avoid some allocations the code would probably need to be restructured to not return NcOptions).
The benefit of using Path is you don't need to (most likely uselessly) check if the path is valid UTF-8 before converting it into a string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know what you mean now. Thank you for the explanation.
src/networking/nc/mod.rs
Outdated
|
|
||
| let mut unix_dg_tmp_socket = String::new(); | ||
|
|
||
| /* Get name of temporary socket for unix datagram client */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think most people use // for single-line comments in Rust.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
| opts: &'a NcOptions, | ||
| poll: Poll, | ||
| net_interest: Ready, | ||
| event_stdin: EventedFd<'a>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because of UtilSetup, this will need to check setup.input().raw_fd() rather than just using stdin. If the result is None, we can just assume there is no input (it's either something like Vec<u8>, which has no file descriptor, or io::Empty).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/networking/nc/mod.rs
Outdated
| unix_dg_tmp_socket = if s_addr.is_some() { | ||
| s_addr.clone().unwrap() | ||
| } else { | ||
| let nf = NamedTempFile::new()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this actually work? I'd assume the temporary file would be dropped and deleted at the end of scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It works.
src/networking/nc/mod.rs
Outdated
| self.netinbufpos >= BUFSIZE | ||
| } | ||
|
|
||
| fn remove_stdin(&mut self) -> std::io::Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably use io::Result<()> instead of std::io::Result<()>.
mssun
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a lot of space to improve your code quality. Please try to polish it multiple times.
build.rs
Outdated
| hashmap.insert("head", "posix"); | ||
| hashmap.insert("sh", "posix"); | ||
| hashmap.insert("sleep", "posix"); | ||
| hashmap.insert("nc", "networking"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line should be put with ping (which is in the "networking section).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/networking/nc/mod.rs
Outdated
| let mut portlist = vec!(); | ||
| let lflag = matches.is_present("l"); | ||
| let mut host = String::from("127.0.0.1"); | ||
| let uport:String; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be a space after :.
let uport: String;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
0bf5436 to
e5f036d
Compare
Codecov Report
@@ Coverage Diff @@
## master #28 +/- ##
==========================================
- Coverage 19.95% 17.96% -1.99%
==========================================
Files 46 47 +1
Lines 4680 5198 +518
Branches 1081 1274 +193
==========================================
Hits 934 934
- Misses 3355 3873 +518
Partials 391 391
Continue to review full report at Codecov.
|
Fix portrange.
|
I plan to refactor your code. Could you help me to write some integration tests? Thanks. |
Main features of netcat is added. The rest remains to be added.