-
Notifications
You must be signed in to change notification settings - Fork 124
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
Added Linux support to qc_handle_{accept,bind,connect} functions. #23
base: master
Are you sure you want to change the base?
Changes from 3 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,74 @@ static int32_t find_free_socket(void) { | |||||||||||||||||||||||||||||
return -1; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
/* NETWORK_HACK: | ||||||||||||||||||||||||||||||
See `guest-services/socket.h`: | ||||||||||||||||||||||||||||||
Darwin still uses `sin_len` in sockaddr, | ||||||||||||||||||||||||||||||
causing errors when copying memory from iOS. | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
#ifdef __APPLE__ | ||||||||||||||||||||||||||||||
# define ADDR addr | ||||||||||||||||||||||||||||||
# undef NETWORK_HACK | ||||||||||||||||||||||||||||||
#else /* Linux, etc. */ | ||||||||||||||||||||||||||||||
# define ADDR darwin_addr | ||||||||||||||||||||||||||||||
# define NETWORK_HACK 1 | ||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
static int convert_error(int err) { | ||||||||||||||||||||||||||||||
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. I'd suggest a function name that makes the platform clear, such as |
||||||||||||||||||||||||||||||
#ifndef NETWORK_HACK | ||||||||||||||||||||||||||||||
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.
Suggested change
|
||||||||||||||||||||||||||||||
return err; | ||||||||||||||||||||||||||||||
#else /* linux */ | ||||||||||||||||||||||||||||||
int result; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
switch(err) { | ||||||||||||||||||||||||||||||
case EAGAIN: | ||||||||||||||||||||||||||||||
/* case EWOULDBLOCK: */ | ||||||||||||||||||||||||||||||
result = 35; | ||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||
case EDEADLK: | ||||||||||||||||||||||||||||||
/* case EDEADLOCK: */ | ||||||||||||||||||||||||||||||
result = 11; | ||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||
/* case {...}: */ | ||||||||||||||||||||||||||||||
default: | ||||||||||||||||||||||||||||||
result = err; | ||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
return result; | ||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
static struct sockaddr_in convert_sockaddr_to(S_SOCKADDR_IN from) { | ||||||||||||||||||||||||||||||
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. Notice that you only call this function when
Suggested change
|
||||||||||||||||||||||||||||||
#ifndef NETWORK_HACK | ||||||||||||||||||||||||||||||
return from; | ||||||||||||||||||||||||||||||
#else | ||||||||||||||||||||||||||||||
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. Redundant... |
||||||||||||||||||||||||||||||
struct sockaddr_in to; | ||||||||||||||||||||||||||||||
to.sin_family = from.sin_family; | ||||||||||||||||||||||||||||||
to.sin_port = from.sin_port; | ||||||||||||||||||||||||||||||
to.sin_addr = from.sin_addr; | ||||||||||||||||||||||||||||||
memset(&to.sin_zero, 0, sizeof(to.sin_zero)); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return to; | ||||||||||||||||||||||||||||||
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. Can use modern features (compound literals and struct initialization) to make code more compact, something like:
Suggested change
|
||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
static S_SOCKADDR_IN convert_sockaddr_from(struct sockaddr_in from) { | ||||||||||||||||||||||||||||||
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. Same as above...
Suggested change
|
||||||||||||||||||||||||||||||
#ifndef NETWORK_HACK | ||||||||||||||||||||||||||||||
return from; | ||||||||||||||||||||||||||||||
#else | ||||||||||||||||||||||||||||||
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. Redundant... |
||||||||||||||||||||||||||||||
S_SOCKADDR_IN to; | ||||||||||||||||||||||||||||||
to.sin_family = from.sin_family; | ||||||||||||||||||||||||||||||
to.sin_port = from.sin_port; | ||||||||||||||||||||||||||||||
to.sin_addr = from.sin_addr; | ||||||||||||||||||||||||||||||
to.sin_len = sizeof(to); | ||||||||||||||||||||||||||||||
memset(&to.sin_zero, 0, sizeof(to.sin_zero)); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return to; | ||||||||||||||||||||||||||||||
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. Same as above...
Suggested change
I know I'm using |
||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
int32_t qc_handle_socket(CPUState *cpu, int32_t domain, int32_t type, | ||||||||||||||||||||||||||||||
int32_t protocol) | ||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||
|
@@ -49,44 +117,59 @@ 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 = convert_error(errno); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return retval; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
int32_t qc_handle_accept(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | ||||||||||||||||||||||||||||||
socklen_t *g_addrlen) | ||||||||||||||||||||||||||||||
int32_t qc_handle_accept(CPUState *cpu, int32_t sckt, S_SOCKADDR *g_addr, | ||||||||||||||||||||||||||||||
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. S_SOCKADDR can always be |
||||||||||||||||||||||||||||||
SOCKLEN_T *g_addrlen) | ||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||
struct sockaddr_in addr; | ||||||||||||||||||||||||||||||
socklen_t addrlen; | ||||||||||||||||||||||||||||||
SOCKLEN_T addrlen; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
addrlen = sizeof(addr); | ||||||||||||||||||||||||||||||
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.
Suggested change
|
||||||||||||||||||||||||||||||
VERIFY_FD(sckt); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
int retval = find_free_socket(); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// 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] = | ||||||||||||||||||||||||||||||
#ifdef NETWORK_HACK | ||||||||||||||||||||||||||||||
accept4(guest_svcs_fds[sckt], | ||||||||||||||||||||||||||||||
(struct sockaddr *) &addr, | ||||||||||||||||||||||||||||||
&addrlen, SOCK_NONBLOCK)) < 0) | ||||||||||||||||||||||||||||||
aronsky marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||
#else | ||||||||||||||||||||||||||||||
accept(guest_svcs_fds[sckt], | ||||||||||||||||||||||||||||||
(struct sockaddr *) &addr, | ||||||||||||||||||||||||||||||
&addrlen)) < 0) { | ||||||||||||||||||||||||||||||
&addrlen)) < 0) | ||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||
retval = -1; | ||||||||||||||||||||||||||||||
guest_svcs_errno = errno; | ||||||||||||||||||||||||||||||
guest_svcs_errno = convert_error(errno); | ||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &addr, | ||||||||||||||||||||||||||||||
sizeof(addr), 1); | ||||||||||||||||||||||||||||||
#ifdef NETWORK_HACK | ||||||||||||||||||||||||||||||
S_SOCKADDR_IN ADDR = convert_sockaddr_from(addr); | ||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &ADDR, | ||||||||||||||||||||||||||||||
sizeof(ADDR), 1); | ||||||||||||||||||||||||||||||
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.
Suggested change
|
||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_addrlen, | ||||||||||||||||||||||||||||||
(uint8_t*) &addrlen, sizeof(addrlen), 1); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return retval; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
int32_t qc_handle_bind(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | ||||||||||||||||||||||||||||||
socklen_t addrlen) | ||||||||||||||||||||||||||||||
int32_t qc_handle_bind(CPUState *cpu, int32_t sckt, S_SOCKADDR *g_addr, | ||||||||||||||||||||||||||||||
SOCKLEN_T addrlen) | ||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||
struct sockaddr_in addr; | ||||||||||||||||||||||||||||||
#ifdef NETWORK_HACK | ||||||||||||||||||||||||||||||
S_SOCKADDR_IN ADDR; | ||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
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. This will necessarily be |
||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
VERIFY_FD(sckt); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
|
@@ -95,25 +178,34 @@ int32_t qc_handle_bind(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | |||||||||||||||||||||||||||||
if (addrlen > sizeof(addr)) { | ||||||||||||||||||||||||||||||
guest_svcs_errno = ENOMEM; | ||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &addr, | ||||||||||||||||||||||||||||||
sizeof(addr), 0); | ||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &ADDR, | ||||||||||||||||||||||||||||||
sizeof(ADDR), 0); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
#ifdef NETWORK_HACK | ||||||||||||||||||||||||||||||
addr = convert_sockaddr_to(ADDR); | ||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
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. Similar to the change in
Suggested change
|
||||||||||||||||||||||||||||||
if ((retval = bind(guest_svcs_fds[sckt], (struct sockaddr *) &addr, | ||||||||||||||||||||||||||||||
addrlen)) < 0) { | ||||||||||||||||||||||||||||||
guest_svcs_errno = errno; | ||||||||||||||||||||||||||||||
guest_svcs_errno = convert_error(errno); | ||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &addr, | ||||||||||||||||||||||||||||||
sizeof(addr), 1); | ||||||||||||||||||||||||||||||
#ifdef NETWORK_HACK | ||||||||||||||||||||||||||||||
ADDR = convert_sockaddr_from(addr); | ||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &ADDR, | ||||||||||||||||||||||||||||||
sizeof(ADDR), 1); | ||||||||||||||||||||||||||||||
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.
Suggested change
|
||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return retval; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
int32_t qc_handle_connect(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | ||||||||||||||||||||||||||||||
socklen_t addrlen) | ||||||||||||||||||||||||||||||
int32_t qc_handle_connect(CPUState *cpu, int32_t sckt, S_SOCKADDR *g_addr, | ||||||||||||||||||||||||||||||
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. Similar to |
||||||||||||||||||||||||||||||
SOCKLEN_T addrlen) | ||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||
struct sockaddr_in addr; | ||||||||||||||||||||||||||||||
#ifdef NETWORK_HACK | ||||||||||||||||||||||||||||||
S_SOCKADDR_IN ADDR; | ||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
VERIFY_FD(sckt); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
|
@@ -122,13 +214,18 @@ int32_t qc_handle_connect(CPUState *cpu, int32_t sckt, struct sockaddr *g_addr, | |||||||||||||||||||||||||||||
if (addrlen > sizeof(addr)) { | ||||||||||||||||||||||||||||||
guest_svcs_errno = ENOMEM; | ||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &addr, | ||||||||||||||||||||||||||||||
sizeof(addr), 0); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &ADDR, | ||||||||||||||||||||||||||||||
sizeof(ADDR), 0); | ||||||||||||||||||||||||||||||
#ifdef NETWORK_HACK | ||||||||||||||||||||||||||||||
addr = convert_sockaddr_to(ADDR); | ||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
if ((retval = connect(guest_svcs_fds[sckt], (struct sockaddr *) &addr, | ||||||||||||||||||||||||||||||
addrlen)) < 0) { | ||||||||||||||||||||||||||||||
guest_svcs_errno = errno; | ||||||||||||||||||||||||||||||
guest_svcs_errno = convert_error(errno); | ||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||
#ifdef NETWORK_HACK | ||||||||||||||||||||||||||||||
ADDR = convert_sockaddr_from(addr); | ||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_addr, (uint8_t*) &addr, | ||||||||||||||||||||||||||||||
sizeof(addr), 1); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
@@ -144,7 +241,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 = convert_error(errno); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return retval; | ||||||||||||||||||||||||||||||
|
@@ -162,7 +259,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 = convert_error(errno); | ||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||
cpu_memory_rw_debug(cpu, (target_ulong) g_buffer, buffer, retval, 1); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
@@ -184,7 +281,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 = convert_error(errno); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
|
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's no reason for the
NETWORK_HACK
andADDR
defines, we can condition the functions based on__APPLE__
only.