Prepare TCP connect

This commit is contained in:
Baptiste Wicht 2016-09-13 22:10:08 +02:00
parent 26fabfd6f1
commit 5be0a1a22b
6 changed files with 90 additions and 3 deletions

View File

@ -112,6 +112,15 @@ std::expected<void> listen(socket_fd_t socket_fd, bool listen);
*/ */
std::expected<size_t> client_bind(socket_fd_t socket_fd); std::expected<size_t> client_bind(socket_fd_t socket_fd);
/*!
* \brief Bind a socket stream as a client (bind a local random port)
* \param socket_fd The file descriptor of the packet
* \param server The ip address of the server
* \param port The port of the server
* \return the allocated port on success and a negative error code otherwise
*/
std::expected<size_t> connect(socket_fd_t socket_fd, network::ip::address address, size_t port);
/*! /*!
* \brief Wait for a packet * \brief Wait for a packet
* \param socket_fd The file descriptor of the packet * \param socket_fd The file descriptor of the packet

View File

@ -237,12 +237,12 @@ std::expected<network::socket_fd_t> network::open(network::socket_domain domain,
} }
// Make sure the socket type is valid // Make sure the socket type is valid
if(type != socket_type::RAW && type != socket_type::DGRAM){ if(type != socket_type::RAW && type != socket_type::DGRAM && type != socket_type::STREAM){
return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_TYPE); return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_TYPE);
} }
// Make sure the socket protocol is valid // Make sure the socket protocol is valid
if(protocol != socket_protocol::ICMP && protocol != socket_protocol::DNS){ if(protocol != socket_protocol::ICMP && protocol != socket_protocol::DNS && protocol != socket_protocol::TCP){
return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_PROTOCOL); return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_PROTOCOL);
} }
@ -251,6 +251,11 @@ std::expected<network::socket_fd_t> network::open(network::socket_domain domain,
return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_TYPE_PROTOCOL); return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_TYPE_PROTOCOL);
} }
// Make sure the socket protocol is valid for the given socket type
if(type == socket_type::STREAM && !(protocol == socket_protocol::TCP)){
return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_TYPE_PROTOCOL);
}
return scheduler::register_new_socket(domain, type, protocol); return scheduler::register_new_socket(domain, type, protocol);
} }
@ -372,7 +377,27 @@ std::expected<size_t> network::client_bind(socket_fd_t socket_fd){
socket.local_port = local_port++; socket.local_port = local_port++;
logging::logf(logging::log_level::TRACE, "network: %u socket %u was assigned port %u\n", scheduler::get_pid(), socket_fd, socket.local_port); logging::logf(logging::log_level::TRACE, "network: %u datagram socket %u was assigned port %u\n", scheduler::get_pid(), socket_fd, socket.local_port);
return std::make_expected<size_t>(socket.local_port);
}
std::expected<size_t> network::connect(socket_fd_t socket_fd, network::ip::address server, size_t port){
if(!scheduler::has_socket(socket_fd)){
return std::make_unexpected<size_t>(std::ERROR_SOCKET_INVALID_FD);
}
auto& socket = scheduler::get_socket(socket_fd);
if(socket.type != socket_type::STREAM){
return std::make_unexpected<size_t>(std::ERROR_SOCKET_INVALID_TYPE);
}
socket.local_port = local_port++;
logging::logf(logging::log_level::TRACE, "network: %u stream socket %u was assigned port %u\n", scheduler::get_pid(), socket_fd, socket.local_port);
//TODO TCP connect
return std::make_expected<size_t>(socket.local_port); return std::make_expected<size_t>(socket.local_port);
} }

View File

@ -424,6 +424,15 @@ void sc_client_bind(interrupt::syscall_regs* regs){
regs->rax = expected_to_i64(status); regs->rax = expected_to_i64(status);
} }
void sc_connect(interrupt::syscall_regs* regs){
auto socket_fd = regs->rbx;
auto ip = regs->rcx;
auto port = regs->rdx;
auto status = network::connect(socket_fd, ip, port);
regs->rax = expected_to_i64(status);
}
void sc_wait_for_packet(interrupt::syscall_regs* regs){ void sc_wait_for_packet(interrupt::syscall_regs* regs){
auto socket_fd = regs->rbx; auto socket_fd = regs->rbx;
auto user_buffer = reinterpret_cast<char*>(regs->rcx); auto user_buffer = reinterpret_cast<char*>(regs->rcx);
@ -692,6 +701,10 @@ void system_call_entry(interrupt::syscall_regs* regs){
sc_client_bind(regs); sc_client_bind(regs);
break; break;
case 0x3008:
sc_connect(regs);
break;
// Special system calls // Special system calls
case 0x6666: case 0x6666:

View File

@ -27,8 +27,18 @@ int main(int argc, char* argv[]) {
std::string port_str(argv[2]); std::string port_str(argv[2]);
auto port = std::atoui(port_str); auto port = std::atoui(port_str);
auto ip_parts = std::split(server, '.');
if (ip_parts.size() != 4) {
tlib::print_line("Invalid address IP for the server");
return 1;
}
auto server_ip = tlib::ip::make_address(std::atoui(ip_parts[0]), std::atoui(ip_parts[1]), std::atoui(ip_parts[2]), std::atoui(ip_parts[3]));
tlib::socket sock(tlib::socket_domain::AF_INET, tlib::socket_type::STREAM, tlib::socket_protocol::TCP); tlib::socket sock(tlib::socket_domain::AF_INET, tlib::socket_type::STREAM, tlib::socket_protocol::TCP);
sock.connect(server_ip, port);
sock.listen(true); sock.listen(true);
if (!sock) { if (!sock) {

View File

@ -42,6 +42,7 @@ std::expected<packet> prepare_packet(size_t socket_fd, void* desc);
std::expected<void> finalize_packet(size_t socket_fd, const packet& p); std::expected<void> finalize_packet(size_t socket_fd, const packet& p);
std::expected<void> listen(size_t socket_fd, bool l); std::expected<void> listen(size_t socket_fd, bool l);
std::expected<size_t> client_bind(size_t socket_fd); std::expected<size_t> client_bind(size_t socket_fd);
std::expected<size_t> connect(size_t socket_fd, tlib::ip::address server, size_t port);
std::expected<packet> wait_for_packet(size_t socket_fd); std::expected<packet> wait_for_packet(size_t socket_fd);
std::expected<packet> wait_for_packet(size_t socket_fd, size_t ms); std::expected<packet> wait_for_packet(size_t socket_fd, size_t ms);
@ -83,6 +84,8 @@ struct socket {
*/ */
void client_bind(); void client_bind();
void connect(tlib::ip::address server, size_t port);
void listen(bool l); void listen(bool l);
packet prepare_packet(void* desc); packet prepare_packet(void* desc);

View File

@ -120,6 +120,20 @@ std::expected<size_t> tlib::client_bind(size_t socket_fd) {
} }
} }
std::expected<size_t> tlib::connect(size_t socket_fd, tlib::ip::address server, size_t port) {
int64_t code;
asm volatile("mov rax, 0x3008; mov rbx, %[socket]; mov rcx, %[ip]; mov rdx, %[port]; int 50; mov %[code], rax"
: [code] "=m"(code)
: [socket] "g" (socket_fd), [ip] "g" (size_t(server.raw_address)), [port] "g" (port)
: "rax", "rbx", "rcx", "rdx");
if (code < 0) {
return std::make_unexpected<size_t, size_t>(-code);
} else {
return std::make_expected<size_t>(code);
}
}
std::expected<tlib::packet> tlib::wait_for_packet(size_t socket_fd) { std::expected<tlib::packet> tlib::wait_for_packet(size_t socket_fd) {
auto buffer = malloc(2048); auto buffer = malloc(2048);
@ -225,6 +239,19 @@ void tlib::socket::client_bind() {
local_port = *status; local_port = *status;
} }
void tlib::socket::connect(tlib::ip::address server, size_t port) {
if (!good() || !open()) {
return;
}
auto status = tlib::connect(fd, server, port);
if (!status) {
error_code = status.error();
}
local_port = *status;
}
tlib::packet tlib::socket::prepare_packet(void* desc) { tlib::packet tlib::socket::prepare_packet(void* desc) {
if (!good() || !open()) { if (!good() || !open()) {
return tlib::packet(); return tlib::packet();