-
Notifications
You must be signed in to change notification settings - Fork 128
Added Linux support to qc_handle_{accept,bind,connect} functions. #23
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?
Changes from 4 commits
0839660
59a223a
1377261
df08c4c
1f63f61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,59 @@ static int32_t find_free_socket(void) { | |
| return -1; | ||
| } | ||
|
|
||
|
|
||
| #ifndef __APPLE__ | ||
| /* convert_sockaddr_from/to darwin: | ||
| See `guest-services/socket.h`: | ||
| * Darwin still uses `sin_len` in sockaddr, | ||
| causing errors when copying memory from iOS. | ||
| */ | ||
| static struct sockaddr_in convert_sockaddr_from_darwin(struct darwin_sockaddr_in from) { | ||
| return (struct sockaddr_in) { | ||
| from.sin_family, | ||
| from.sin_port, | ||
| from.sin_addr, | ||
| { [0 ... sizeof(from.sin_zero) - 1] = 0 } }; | ||
| } | ||
|
|
||
| static struct darwin_sockaddr_in convert_sockaddr_to_darwin(struct sockaddr_in from) { | ||
| return (struct darwin_sockaddr_in) { | ||
| sizeof(from), | ||
| from.sin_family, | ||
| from.sin_port, | ||
| from.sin_addr, | ||
| { [0 ... sizeof(from.sin_zero) - 1] = 0 } }; | ||
| } | ||
| #endif | ||
|
|
||
| /* darwin_error: | ||
| At compile-time, redefine what errors mean to tcp-tunnel before sending them. | ||
| */ | ||
| static int darwin_error(int err) { | ||
| #ifdef __APPLE__ | ||
| return err; | ||
| #else | ||
| int result; | ||
|
|
||
| switch(err) { | ||
| case EAGAIN: | ||
| /* case EWOULDBLOCK: */ | ||
| result = 35; | ||
| break; | ||
| case EDEADLK: | ||
| /* case EDEADLOCK: */ | ||
| result = 11; | ||
| break; | ||
| default: | ||
| result = err; | ||
| break; | ||
| } | ||
|
|
||
| return result; | ||
| #endif | ||
| } | ||
|
|
||
|
|
||
| int32_t qc_handle_socket(CPUState *cpu, int32_t domain, int32_t type, | ||
| int32_t protocol) | ||
| { | ||
|
|
@@ -49,17 +102,17 @@ int32_t qc_handle_socket(CPUState *cpu, int32_t domain, int32_t type, | |
| guest_svcs_errno = ENOTSOCK; | ||
| } else if ((guest_svcs_fds[retval] = socket(domain, type, protocol)) < 0) { | ||
| retval = -1; | ||
| guest_svcs_errno = errno; | ||
| guest_svcs_errno = darwin_error(errno); | ||
| } | ||
|
|
||
| return retval; | ||
| } | ||
|
|
||
| int32_t qc_handle_accept(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | ||
| int32_t qc_handle_accept(CPUState *cpu, int32_t sckt, struct SOCKADDR *g_addr, | ||
| socklen_t *g_addrlen) | ||
| { | ||
| struct sockaddr_in addr; | ||
| socklen_t addrlen; | ||
| socklen_t addrlen = sizeof(addr); | ||
|
|
||
| VERIFY_FD(sckt); | ||
|
|
||
|
|
@@ -68,12 +121,25 @@ int32_t qc_handle_accept(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | |
| // TODO: timeout | ||
| if (retval < 0) { | ||
| guest_svcs_errno = ENOTSOCK; | ||
| } else if ((guest_svcs_fds[retval] = accept(guest_svcs_fds[sckt], | ||
| } else if ((guest_svcs_fds[retval] = | ||
| #ifndef __APPLE__ | ||
| accept4(guest_svcs_fds[sckt], | ||
| (struct sockaddr *) &addr, | ||
| &addrlen, SOCK_NONBLOCK)) < 0) | ||
| #else | ||
| accept(guest_svcs_fds[sckt], | ||
| (struct sockaddr *) &addr, | ||
| &addrlen)) < 0) { | ||
| &addrlen)) < 0) | ||
| #endif | ||
| { | ||
| retval = -1; | ||
| guest_svcs_errno = errno; | ||
| guest_svcs_errno = darwin_error(errno); | ||
| } else { | ||
| #ifndef __APPLE__ | ||
| struct darwin_sockaddr_in darwin_addr = convert_sockaddr_to_darwin(addr); | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &darwin_addr, | ||
| sizeof(darwin_addr), 1); | ||
| #endif | ||
|
||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &addr, | ||
| sizeof(addr), 1); | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addrlen, | ||
|
|
@@ -83,10 +149,13 @@ int32_t qc_handle_accept(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | |
| return retval; | ||
| } | ||
|
|
||
| int32_t qc_handle_bind(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | ||
| int32_t qc_handle_bind(CPUState *cpu, int32_t sckt, struct SOCKADDR *g_addr, | ||
| socklen_t addrlen) | ||
| { | ||
| struct sockaddr_in addr; | ||
| #ifndef __APPLE__ | ||
| struct darwin_sockaddr_in darwin_addr; | ||
| #endif | ||
|
|
||
| VERIFY_FD(sckt); | ||
|
|
||
|
|
@@ -95,25 +164,39 @@ int32_t qc_handle_bind(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | |
| if (addrlen > sizeof(addr)) { | ||
| guest_svcs_errno = ENOMEM; | ||
| } else { | ||
| #ifndef __APPLE__ | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &darwin_addr, | ||
| sizeof(darwin_addr), 0); | ||
| addr = convert_sockaddr_from_darwin(darwin_addr); | ||
| #else | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &addr, | ||
| sizeof(addr), 0); | ||
|
|
||
| sizeof(addr), 0); | ||
| #endif | ||
| if ((retval = bind(guest_svcs_fds[sckt], (struct sockaddr *) &addr, | ||
| addrlen)) < 0) { | ||
| guest_svcs_errno = errno; | ||
| guest_svcs_errno = darwin_error(errno); | ||
| } else { | ||
| #ifndef __APPLE__ | ||
| darwin_addr = convert_sockaddr_to_darwin(addr); | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &darwin_addr, | ||
| sizeof(darwin_addr), 1); | ||
| #else | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &addr, | ||
| sizeof(addr), 1); | ||
| #endif | ||
| } | ||
| } | ||
|
|
||
| return retval; | ||
| } | ||
|
|
||
| int32_t qc_handle_connect(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | ||
| int32_t qc_handle_connect(CPUState *cpu, int32_t sckt, struct SOCKADDR *g_addr, | ||
| socklen_t addrlen) | ||
| { | ||
| struct sockaddr_in addr; | ||
| #ifndef __APPLE__ | ||
| struct darwin_sockaddr_in darwin_addr; | ||
| #endif | ||
|
|
||
| VERIFY_FD(sckt); | ||
|
|
||
|
|
@@ -122,15 +205,26 @@ int32_t qc_handle_connect(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | |
| if (addrlen > sizeof(addr)) { | ||
| guest_svcs_errno = ENOMEM; | ||
| } else { | ||
| #ifndef __APPLE__ | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &darwin_addr, | ||
| sizeof(darwin_addr), 0); | ||
| addr = convert_sockaddr_from_darwin(darwin_addr); | ||
| #else | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &addr, | ||
| sizeof(addr), 0); | ||
|
|
||
| #endif | ||
| if ((retval = connect(guest_svcs_fds[sckt], (struct sockaddr *) &addr, | ||
| addrlen)) < 0) { | ||
| guest_svcs_errno = errno; | ||
| guest_svcs_errno = darwin_error(errno); | ||
| } else { | ||
| #ifndef __APPLE__ | ||
| darwin_addr = convert_sockaddr_to_darwin(addr); | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &darwin_addr, | ||
| sizeof(darwin_addr), 1); | ||
| #else | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &addr, | ||
| sizeof(addr), 1); | ||
| #endif | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -144,7 +238,7 @@ int32_t qc_handle_listen(CPUState *cpu, int32_t sckt, int32_t backlog) | |
| int retval = 0; | ||
|
|
||
| if ((retval = listen(guest_svcs_fds[sckt], backlog)) < 0) { | ||
| guest_svcs_errno = errno; | ||
| guest_svcs_errno = darwin_error(errno); | ||
| } | ||
|
|
||
| return retval; | ||
|
|
@@ -162,7 +256,7 @@ int32_t qc_handle_recv(CPUState *cpu, int32_t sckt, void *g_buffer, | |
| if (length > MAX_BUF_SIZE) { | ||
| guest_svcs_errno = ENOMEM; | ||
| } else if ((retval = recv(guest_svcs_fds[sckt], buffer, length, flags)) <= 0) { | ||
| guest_svcs_errno = errno; | ||
| guest_svcs_errno = darwin_error(errno); | ||
| } else { | ||
| cpu_memory_rw_debug(cpu, (target_ulong) g_buffer, buffer, retval, 1); | ||
| } | ||
|
|
@@ -184,7 +278,7 @@ int32_t qc_handle_send(CPUState *cpu, int32_t sckt, void *g_buffer, | |
| cpu_memory_rw_debug(cpu, (target_ulong) g_buffer, buffer, length, 0); | ||
|
|
||
| if ((retval = send(guest_svcs_fds[sckt], buffer, length, flags)) < 0) { | ||
| guest_svcs_errno = errno; | ||
| guest_svcs_errno = darwin_error(errno); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,6 +32,37 @@ | |
| #include "sys/socket.h" | ||
| #endif | ||
|
|
||
| #ifdef __APPLE__ | ||
| #define SOCKADDR sockaddr | ||
| #define SOCKADDR_IN sockaddr_in | ||
|
Comment on lines
+36
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for these defines. You can use |
||
| #else /* __linux__ */ | ||
| /* XXX: A lot of this is defined by the standard. | ||
| But doesn't hurt to ensure Darwin/BSD lengths. | ||
MCApollo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| - in_addr_t should be uint32 on all systems: | ||
| typedef unsigned int in_addr_t; | ||
| struct in_addr { | ||
| in_addr_t s_addr; | ||
| }; | ||
| */ | ||
|
|
||
| struct darwin_sockaddr { | ||
| unsigned char sa_len; | ||
| unsigned char sa_family; | ||
| char sa_data[14]; | ||
| }; | ||
| struct darwin_sockaddr_in { | ||
| unsigned char sin_len; | ||
| unsigned char sin_family; | ||
| unsigned short sin_port; | ||
| struct in_addr sin_addr; | ||
| char sin_zero[8]; | ||
| }; | ||
|
|
||
| #define SOCKADDR darwin_sockaddr | ||
| #define SOCKADDR_IN darwin_sockaddr_in | ||
| #endif | ||
|
|
||
| #pragma GCC diagnostic push | ||
| #pragma GCC diagnostic ignored "-Wredundant-decls" | ||
| extern int32_t guest_svcs_errno; | ||
|
|
@@ -47,13 +78,13 @@ typedef struct __attribute__((packed)) { | |
|
|
||
| typedef struct __attribute__((packed)) { | ||
| int32_t socket; | ||
| struct sockaddr *addr; | ||
| struct SOCKADDR *addr; | ||
| socklen_t *addrlen; | ||
| } qc_accept_args_t; | ||
|
|
||
| typedef struct __attribute__((packed)) { | ||
| int32_t socket; | ||
| struct sockaddr *addr; | ||
| struct SOCKADDR *addr; | ||
| socklen_t addrlen; | ||
| } qc_bind_args_t, qc_connect_args_t; | ||
|
|
||
|
|
@@ -72,11 +103,11 @@ typedef struct __attribute__((packed)) { | |
| #ifndef OUT_OF_TREE_BUILD | ||
| int32_t qc_handle_socket(CPUState *cpu, int32_t domain, int32_t type, | ||
| int32_t protocol); | ||
| int32_t qc_handle_accept(CPUState *cpu, int32_t sckt, struct sockaddr *addr, | ||
| int32_t qc_handle_accept(CPUState *cpu, int32_t sckt, struct SOCKADDR *addr, | ||
| socklen_t *addrlen); | ||
| int32_t qc_handle_bind(CPUState *cpu, int32_t sckt, struct sockaddr *addr, | ||
| int32_t qc_handle_bind(CPUState *cpu, int32_t sckt, struct SOCKADDR *addr, | ||
| socklen_t addrlen); | ||
| int32_t qc_handle_connect(CPUState *cpu, int32_t sckt, struct sockaddr *addr, | ||
| int32_t qc_handle_connect(CPUState *cpu, int32_t sckt, struct SOCKADDR *addr, | ||
| socklen_t addrlen); | ||
| int32_t qc_handle_listen(CPUState *cpu, int32_t sckt, int32_t backlog); | ||
| int32_t qc_handle_recv(CPUState *cpu, int32_t sckt, void *buffer, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.