mirror of
https://github.com/vanilla-wiiu/vanilla.git
synced 2025-01-22 08:11:47 -05:00
use custom dhcp script
Greatly improves routing behavior. Rather than letting dhclient perform routing and then "correct" it after the fact, we replace dhclient's behavior entirely. Rather than add a system-wide route to 192.168.1.10, we bind our socket to the interface so no conflicts will occur with any other device on the network named 192.168.1.10. No system-wide route is made via the wireless interface for 192.168.1.0/24 or for 192.168.1.10. Fixes #96
This commit is contained in:
parent
7be31c5169
commit
5f86ab1498
3 changed files with 69 additions and 55 deletions
|
@ -35,6 +35,12 @@ add_custom_command(
|
|||
DEPENDS wpa_supplicant_build
|
||||
)
|
||||
|
||||
# Install dhcp script
|
||||
add_custom_target(
|
||||
dhcp_script ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/dhcp.sh" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../sbin/dhcp.sh"
|
||||
)
|
||||
|
||||
# Build client library
|
||||
add_custom_target(
|
||||
wpa_client_build
|
||||
|
|
20
pipe/linux/dhcp.sh
Executable file
20
pipe/linux/dhcp.sh
Executable file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
|
||||
ip=/sbin/ip
|
||||
|
||||
case "$reason" in
|
||||
PREINIT)
|
||||
${ip} -4 link set dev ${interface} up
|
||||
;;
|
||||
BOUND|RENEW|REBIND|REBOOT)
|
||||
# Add IP address to interface. Provide no subnet so OS doesn't think there's a network here.
|
||||
${ip} -4 addr flush dev ${interface}
|
||||
${ip} -4 addr add ${new_ip_address}/32 dev ${interface}
|
||||
|
||||
;;
|
||||
EXPIRE|FAIL|RELEASE|STOP)
|
||||
# Remove old IP address
|
||||
${ip} -4 addr flush dev ${interface}
|
||||
|
||||
;;
|
||||
esac
|
|
@ -53,6 +53,11 @@ struct sync_args {
|
|||
struct wpa_ctrl *ctrl;
|
||||
};
|
||||
|
||||
struct relay_info {
|
||||
const char *wireless_interface;
|
||||
in_port_t port;
|
||||
};
|
||||
|
||||
#define THREADRESULT(x) ((void *) (uintptr_t) (x))
|
||||
|
||||
void lpprint(const char *fmt, va_list args)
|
||||
|
@ -157,14 +162,14 @@ int wait_for_output(int pipe, const char *expected_output)
|
|||
static const int max_attempts = 5;
|
||||
int nbytes, attempts = 0, success = 0;
|
||||
const int expected_len = strlen(expected_output);
|
||||
char buf[100];
|
||||
char buf[256];
|
||||
int read_count = 0;
|
||||
int ret = 0;
|
||||
do {
|
||||
// Read line from child process
|
||||
read_line_from_pipe(pipe, buf, sizeof(buf));
|
||||
ssize_t read_sz = read_line_from_pipe(pipe, buf, sizeof(buf));
|
||||
|
||||
print_info("SUBPROCESS %s", buf);
|
||||
print_info("SUBPROCESS %.*s", read_sz, buf);
|
||||
|
||||
// We got success message!
|
||||
if (!memcmp(buf, expected_output, expected_len)) {
|
||||
|
@ -406,40 +411,35 @@ die:
|
|||
|
||||
int call_dhcp(const char *network_interface, pid_t *dhclient_pid)
|
||||
{
|
||||
const char *argv[] = {"dhclient", "-d", "--no-pid", network_interface, NULL, NULL, NULL};
|
||||
|
||||
// See if dhclient exists in our local directories
|
||||
size_t buf_size = get_max_path_length();
|
||||
char *dhclient_buf = malloc(buf_size);
|
||||
char *dhclient_script = NULL;
|
||||
char *dhclient_script = malloc(buf_size);
|
||||
get_binary_in_working_directory("dhclient", dhclient_buf, buf_size);
|
||||
get_binary_in_working_directory("../sbin/dhcp.sh", dhclient_script, buf_size);
|
||||
|
||||
if (access(dhclient_buf, F_OK) == 0) {
|
||||
// HACK: Assume we're working in our deployed environment
|
||||
// TODO: Should probably just incorporate dhclient (or something like it) directly as a library
|
||||
argv[0] = dhclient_buf;
|
||||
argv[4] = "-sf";
|
||||
|
||||
dhclient_script = malloc(buf_size);
|
||||
get_binary_in_working_directory("../sbin/dhclient-script", dhclient_script, buf_size);
|
||||
argv[5] = dhclient_script;
|
||||
|
||||
print_info("Using custom dhclient at: %s", argv[0]);
|
||||
// Prefer our local dhclient if it's available
|
||||
// TODO: dhclient is EOL and should be replaced with something else
|
||||
print_info("Using custom dhclient at: %s", dhclient_buf);
|
||||
} else {
|
||||
print_info("Using system dhclient");
|
||||
strncpy(dhclient_buf, "dhclient", buf_size);
|
||||
}
|
||||
|
||||
const char *argv[] = {dhclient_buf, "-d", "--no-pid", "-sf", dhclient_script, network_interface, NULL};
|
||||
|
||||
int dhclient_pipe;
|
||||
int r = start_process(argv, dhclient_pid, NULL, &dhclient_pipe);
|
||||
if (r != VANILLA_SUCCESS) {
|
||||
print_info("FAILED TO CALL DHCLIENT");
|
||||
free(dhclient_buf);
|
||||
free(dhclient_script);
|
||||
return r;
|
||||
}
|
||||
|
||||
free(dhclient_buf);
|
||||
free(dhclient_script);
|
||||
|
||||
if (r != VANILLA_SUCCESS) {
|
||||
print_info("FAILED TO CALL DHCLIENT");
|
||||
return r;
|
||||
}
|
||||
|
||||
if (wait_for_output(dhclient_pipe, "bound to")) {
|
||||
return VANILLA_SUCCESS;
|
||||
} else {
|
||||
|
@ -581,7 +581,8 @@ int open_socket(in_port_t port)
|
|||
|
||||
void *open_relay(void *data)
|
||||
{
|
||||
in_port_t port = (in_port_t) (uintptr_t) data;
|
||||
struct relay_info *info = (struct relay_info *) data;
|
||||
in_port_t port = info->port;
|
||||
int ret = -1;
|
||||
|
||||
// Open an incoming port from the console
|
||||
|
@ -590,6 +591,8 @@ void *open_relay(void *data)
|
|||
goto close;
|
||||
}
|
||||
|
||||
setsockopt(from_console, SOL_SOCKET, SO_BINDTODEVICE, info->wireless_interface, strlen(info->wireless_interface));
|
||||
|
||||
// Open an incoming port from the frontend
|
||||
int from_frontend = open_socket(port + 100);
|
||||
if (from_frontend == -1) {
|
||||
|
@ -628,15 +631,25 @@ close:
|
|||
return THREADRESULT(ret);
|
||||
}
|
||||
|
||||
void create_all_relays()
|
||||
void create_all_relays(const char *wireless_interface)
|
||||
{
|
||||
pthread_t vid_thread, aud_thread, msg_thread, cmd_thread, hid_thread;
|
||||
struct relay_info vid_info, aud_info, msg_info, cmd_info, hid_info;
|
||||
|
||||
pthread_create(&vid_thread, NULL, open_relay, THREADRESULT(PORT_VID));
|
||||
pthread_create(&aud_thread, NULL, open_relay, THREADRESULT(PORT_AUD));
|
||||
pthread_create(&msg_thread, NULL, open_relay, THREADRESULT(PORT_MSG));
|
||||
pthread_create(&cmd_thread, NULL, open_relay, THREADRESULT(PORT_CMD));
|
||||
pthread_create(&hid_thread, NULL, open_relay, THREADRESULT(PORT_HID));
|
||||
// Set wireless interface on all
|
||||
vid_info.wireless_interface = aud_info.wireless_interface = msg_info.wireless_interface = cmd_info.wireless_interface = hid_info.wireless_interface = wireless_interface;
|
||||
|
||||
vid_info.port = PORT_VID;
|
||||
aud_info.port = PORT_AUD;
|
||||
msg_info.port = PORT_MSG;
|
||||
cmd_info.port = PORT_CMD;
|
||||
hid_info.port = PORT_HID;
|
||||
|
||||
pthread_create(&vid_thread, NULL, open_relay, &vid_info);
|
||||
pthread_create(&aud_thread, NULL, open_relay, &aud_info);
|
||||
pthread_create(&msg_thread, NULL, open_relay, &msg_info);
|
||||
pthread_create(&cmd_thread, NULL, open_relay, &cmd_info);
|
||||
pthread_create(&hid_thread, NULL, open_relay, &hid_info);
|
||||
|
||||
pthread_join(vid_thread, NULL);
|
||||
pthread_join(aud_thread, NULL);
|
||||
|
@ -645,27 +658,6 @@ void create_all_relays()
|
|||
pthread_join(hid_thread, NULL);
|
||||
}
|
||||
|
||||
int call_ip(const char **argv)
|
||||
{
|
||||
// Destroy default route that dhclient will have created
|
||||
pid_t ip_pid;
|
||||
int r = start_process(argv, &ip_pid, NULL, NULL);
|
||||
if (r != VANILLA_SUCCESS) {
|
||||
print_info("FAILED TO REMOVE CONSOLE ROUTE FROM SYSTEM");
|
||||
return r;
|
||||
}
|
||||
|
||||
int ip_status;
|
||||
waitpid(ip_pid, &ip_status, 0);
|
||||
|
||||
if (!WIFEXITED(ip_status)) {
|
||||
print_info("FAILED TO REMOVE CONSOLE ROUTE FROM SYSTEM");
|
||||
return VANILLA_ERROR;
|
||||
}
|
||||
|
||||
return VANILLA_SUCCESS;
|
||||
}
|
||||
|
||||
void *thread_handler(void *data)
|
||||
{
|
||||
struct sync_args *args = (struct sync_args *) data;
|
||||
|
@ -934,11 +926,7 @@ void *do_connect(void *data)
|
|||
print_info("DHCP ESTABLISHED");
|
||||
}
|
||||
|
||||
call_ip((const char *[]){"ip", "route", "del", "default", "via", "192.168.1.1", "dev", args->wireless_interface, NULL});
|
||||
call_ip((const char *[]){"ip", "route", "del", "192.168.1.0/24", "dev", args->wireless_interface, NULL});
|
||||
call_ip((const char *[]){"route", "add", "-host", "192.168.1.10", "dev", args->wireless_interface, NULL});
|
||||
|
||||
create_all_relays();
|
||||
create_all_relays(args->wireless_interface);
|
||||
|
||||
int kill_ret = kill(dhclient_pid, SIGTERM);
|
||||
print_info("KILLING DHCLIENT %i", dhclient_pid);
|
||||
|
|
Loading…
Reference in a new issue