Smarter selection of the interface

This commit is contained in:
Baptiste Wicht 2016-09-09 16:55:37 +02:00
parent 3093a82f68
commit f8ac9a81a3
3 changed files with 25 additions and 3 deletions

View File

@ -35,6 +35,7 @@ struct packet {
bool user;
uint64_t tags; // This allows for 4 tags (4 layer)
uint64_t interface; ///< Id of the interface
packet() : fd(0), user(false), tags(0) {}
packet(char* payload, size_t payload_size) : payload(payload), payload_size(payload_size), index(0), fd(0), user(false), tags(0) {}

View File

@ -51,6 +51,7 @@ uint16_t type_to_code(network::ethernet::ether_type type){
void prepare_packet(network::ethernet::packet& p, network::interface_descriptor& interface, size_t destination, network::ethernet::ether_type type){
p.type = type;
p.index = sizeof(network::ethernet::header);
p.interface = interface.id;
auto source_mac = interface.mac_address;

View File

@ -26,6 +26,7 @@
#include "net/icmp_layer.hpp"
namespace {
std::vector<network::interface_descriptor> interfaces;
void rx_thread(void* data){
@ -65,6 +66,26 @@ void tx_thread(void* data){
}
}
network::interface_descriptor& select_interface(network::ip::address address){
if(address == network::ip::make_address(127, 0, 0, 1)){
for(auto& interface : interfaces){
if(interface.enabled && interface.driver == "loopback"){
return interface;
}
}
}
// Otherwise return the first enabled interface
for(auto& interface : interfaces){
if(interface.enabled){
return interface;
}
}
thor_unreachable("network: Should never happen");
}
} //end of anonymous namespace
void network::init(){
@ -194,17 +215,16 @@ std::tuple<size_t, size_t> network::prepare_packet(socket_fd_t socket_fd, void*
return {-std::ERROR_SOCKET_INVALID_FD, 0};
}
// TODO A socket should be bound to an interface somehow
if(!network::number_of_interfaces()){
return {-std::ERROR_SOCKET_NO_INTERFACE, 0};
}
auto& interface = network::interface(0);
auto& socket = scheduler::get_socket(socket_fd);
switch(socket.protocol){
case network::socket_protocol::ICMP:
auto descriptor = static_cast<network::icmp::packet_descriptor*>(desc);
auto& interface = select_interface(descriptor->target_ip);
auto packet = network::icmp::prepare_packet(buffer, interface, descriptor->target_ip, descriptor->payload_size, descriptor->type, descriptor->code);
if(packet){
@ -224,7 +244,6 @@ std::expected<void> network::finalize_packet(socket_fd_t socket_fd, size_t packe
return std::make_unexpected<void>(std::ERROR_SOCKET_INVALID_FD);
}
auto& interface = network::interface(0);
auto& socket = scheduler::get_socket(socket_fd);
if(!socket.has_packet(packet_fd)){
@ -232,6 +251,7 @@ std::expected<void> network::finalize_packet(socket_fd_t socket_fd, size_t packe
}
auto& packet = socket.get_packet(packet_fd);
auto& interface = network::interface(packet.interface);
switch(socket.protocol){
case network::socket_protocol::ICMP: