From bf58ee2adc522ea0dbd050d94d3625071eb02d1b Mon Sep 17 00:00:00 2001 From: Razvan Deaconescu Date: Sat, 4 Jun 2011 20:12:39 +0300 Subject: [PATCH] raw: Update list-based socket management functions. --- src/raw/swift_list.c | 195 ++++++++++++++++++++++++++++++------------- src/raw/swift_raw.c | 67 +++++++-------- 2 files changed, 173 insertions(+), 89 deletions(-) diff --git a/src/raw/swift_list.c b/src/raw/swift_list.c index d359845..04832ac 100644 --- a/src/raw/swift_list.c +++ b/src/raw/swift_list.c @@ -17,130 +17,213 @@ #include #include "swift_types.h" -#include "swift_list.h" +#include "socket_manager.h" #include "debug.h" #include "util.h" +enum sock_bind_state { + STATE_NOTBOUND, + STATE_BOUND +}; + +/* socket management structure */ +struct sock_list { + int s; + struct sockaddr addr; + enum sock_bind_state bind_state; + struct sock_list *next; + struct sock_list *prev; +}; + +/* socket management list head */ +static struct sock_list sock_list_head = { + .next = &sock_list_head, + .prev = &sock_list_head +}; + /* - * Add new socket to list. Called by sw_socket "syscall". + * Find socket in socket management list. */ -struct sock_list *list_add_socket(int s) +static struct sock_list *list_get_link(int s) { - struct sock_list *ptr = malloc(sizeof(*ptr)); - if (ptr == NULL) - return NULL; + struct sock_list *ptr; + + for (ptr = sock_list_head.next; ptr != &sock_list_head; ptr = ptr->next) + if (ptr->s == s) + return ptr; + + return NULL; +} + +/* + * Find socket in socket management list by address. + */ + +static struct sock_list *list_get_link_by_address(const struct sockaddr *addr) +{ + struct sock_list *ptr; + + for (ptr = sock_list_head.next; ptr != &sock_list_head; ptr = ptr->next) + if (memcmp(addr, &ptr->addr, sizeof(*addr)) == 0) + return ptr; + + return NULL; +} + +/* + * Unlink socket from list. Called by sm_del. + */ + +static void list_unlink(struct sock_list *ptr) +{ + ptr->next->prev = ptr->prev; + ptr->prev->next = ptr->next; + ptr->next = ptr; + ptr->prev = ptr; +} + +/* + * Link socket to list. Add socket to tail of list. + */ +static void list_link(struct sock_list *ptr) +{ ptr->next = &sock_list_head; ptr->prev = sock_list_head.prev; sock_list_head.prev->next = ptr; sock_list_head.prev = ptr; +} + +/* + * Add new socket to list. Called by sw_socket "syscall". + */ + +int sm_add(int s) +{ + struct sock_list *ptr = malloc(sizeof(*ptr)); + if (ptr == NULL) + return -1; + ptr->s = s; + list_link(ptr); - return ptr; + return 0; } /* * Bind socket to given address. Called by sw_bind "syscall". */ -struct sock_list *list_update_socket_address(int s, __CONST_SOCKADDR_ARG addr) +int sm_update_address(int s, const struct sockaddr *addr) { struct sock_list *ptr; - for (ptr = sock_list_head.next; ptr != &sock_list_head; ptr = ptr->next) - if (ptr->s == s) { - memcpy(&ptr->addr, addr, sizeof(ptr->addr)); - ptr->bind_state = STATE_BOUND; - return ptr; - } + ptr = list_get_link(s); + if (ptr == NULL) + return -1; - return NULL; + memcpy(&ptr->addr, addr, sizeof(ptr->addr)); + + return 0; } /* - * Get list element containing socket s. Called by sw_send* "syscalls". + * Remove socket from list. Called by sw_close "syscall". */ -struct sock_list *list_elem_from_socket(int s) +int sm_del(int s) { struct sock_list *ptr; - for (ptr = sock_list_head.next; ptr != &sock_list_head; ptr = ptr->next) - if (ptr->s == s) - return ptr; + ptr = list_get_link(s); + if (ptr == NULL) + return -1; - return NULL; + list_unlink(ptr); + free(ptr); + + return 0; } /* - * Get list element containing address addr. Called by sw_bind "syscall". + * Check if a socket is bound. */ -struct sock_list *list_elem_from_address(__CONST_SOCKADDR_ARG addr) +int sm_is_bound(int s) { struct sock_list *ptr; - for (ptr = sock_list_head.next; ptr != &sock_list_head; ptr = ptr->next) { - dprintf("socket address to be checked\n"); - if (ptr->bind_state == STATE_NOTBOUND) - continue; - dprintf("bound socket address to be checked\n"); - if (memcmp(&ptr->addr, addr, sizeof(addr)) == 0) - return ptr; - } + ptr = list_get_link(s); + if (ptr == NULL) + return 0; - return NULL; + if (ptr->bind_state == STATE_BOUND) + return 1; + + return 0; } /* - * Unlink socket from list. Called by list_remove_socket. + * Mark socket as bound. */ -static struct sock_list *list_unlink_socket(int s) + +int sm_mark_bound(int s) { struct sock_list *ptr; + + ptr = list_get_link(s); + if (ptr == NULL) + return -1; - for (ptr = sock_list_head.next; ptr != &sock_list_head; ptr = ptr->next) - if (ptr->s == s) { - ptr->next->prev = ptr->prev; - ptr->prev->next = ptr->next; - ptr->next = ptr; - ptr->prev = ptr; - return ptr; - } + ptr->bind_state = STATE_BOUND; - return NULL; + return 0; } /* - * Remove socket from list. Called by sw_close "syscall". + * Mark socket as unbound. */ -int list_remove_socket(int s) +int sm_mark_unbound(int s) { struct sock_list *ptr; - ptr = list_unlink_socket(s); + ptr = list_get_link(s); if (ptr == NULL) return -1; - free(ptr); + ptr->bind_state = STATE_NOTBOUND; + return 0; } /* - * Check if a socket is bound. + * Check if adress is asociated with a given socket. */ -int list_socket_is_bound(int s) + +int sm_address_exists(const struct sockaddr *addr) { struct sock_list *ptr; - for (ptr = sock_list_head.next; ptr != &sock_list_head; ptr = ptr->next) - if (ptr->s == s) { - if (ptr->bind_state == STATE_BOUND) - return 1; - break; - } + ptr = list_get_link_by_address(addr); + if (ptr == NULL) + return 0; - return 0; + return 1; +} + +/* + * Find socket address. + */ + +struct sockaddr *sm_get_address(int s) +{ + struct sock_list *ptr; + + ptr = list_get_link(s); + if (ptr == NULL) + return NULL; + + return &ptr->addr; } diff --git a/src/raw/swift_raw.c b/src/raw/swift_raw.c index 03170e4..27506ac 100644 --- a/src/raw/swift_raw.c +++ b/src/raw/swift_raw.c @@ -25,7 +25,7 @@ #include "swift_types.h" #include "swift_raw.h" -#include "swift_list.h" +#include "socket_manager.h" #include "debug.h" #include "util.h" @@ -39,7 +39,7 @@ int sw_socket(int __domain, int __type, int __protocol) { int s; - struct sock_list *list; + int rc; if (__domain != PF_INET || __type != SOCK_DGRAM || __protocol != IPPROTO_SWIFT) { errno = EINVAL; @@ -51,14 +51,14 @@ int sw_socket(int __domain, int __type, int __protocol) goto sock_err; } - list = list_add_socket(s); - if (list == NULL) { + rc = sm_add(s); + if (rc < 0) { errno = ENOMEM; goto list_add_err; } /* Socket is not bound. */ - list->bind_state = STATE_NOTBOUND; + sm_mark_unbound(s); return s; @@ -75,34 +75,35 @@ sock_err: */ int sw_bind(int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len) { - struct sock_list *list; int rc; - rc = list_socket_is_bound(__fd); + rc = sm_is_bound(__fd); if (rc == 1) { errno = EINVAL; goto socket_bound_err; } /* Check whether address is already in use. */ - list = list_elem_from_address(__addr); - if (list != NULL) { + rc = sm_address_exists(__addr); + if (rc == 1) { errno = EADDRINUSE; - goto list_elem_err; + goto address_err; } /* Update __fd entry in socket management list. */ - list = list_update_socket_address(__fd, __addr); - if (list == NULL) { + rc = sm_update_address(__fd, __addr); + if (rc < 0) { errno = EBADF; - goto list_update_err; + goto update_err; } + sm_mark_bound(__fd); + return 0; +update_err: +address_err: socket_bound_err: -list_update_err: -list_elem_err: return -1; } @@ -110,21 +111,21 @@ list_elem_err: int sw_getsockname(int __fd, __SOCKADDR_ARG __addr, socklen_t *__restrict __len) { - struct sock_list *list; + struct sockaddr *addr; /* Find socket in management structure. */ - list = list_elem_from_socket(__fd); - if (list == NULL) { - errno = EBADF; - goto list_elem_err; + addr = sm_get_address(__fd); + if (addr == NULL) { + errno = EINVAL; + goto address_err; } - memcpy(__addr, &list->addr, sizeof(list->addr)); - *__len = sizeof(list->addr); + memcpy(__addr, &addr, sizeof(addr)); + *__len = sizeof(addr); return 0; -list_elem_err: +address_err: return -1; } @@ -140,13 +141,13 @@ ssize_t sw_sendto(int __fd, __const void *__buf, size_t __n, socklen_t __addr_len) { ssize_t bytes_sent; - struct sock_list *list; struct iovec __iov[1]; struct msghdr __msgh; struct sockaddr_sw *__sw_addr = (struct sockaddr_sw *) __addr; + int rc; - list = list_elem_from_socket(__fd); - if (list != NULL && list->bind_state == STATE_NOTBOUND) { + rc = sm_is_bound(__fd); + if (rc < 0) { errno = EAFNOSUPPORT; goto sock_err; } @@ -190,17 +191,17 @@ ssize_t sw_recvfrom(int __fd, void *__restrict __buf, size_t __n, socklen_t *__restrict __addr_len) { ssize_t bytes_recv; - struct sock_list *list; struct iovec __iov[1]; struct msghdr __msgh; struct sockaddr_sw *__sw_addr = (struct sockaddr_sw *) __addr; + int rc; - list = list_elem_from_socket(__fd); - if (list != NULL && list->bind_state == STATE_NOTBOUND) { + rc = sm_is_bound(__fd); + if (rc < 0) { errno = EAFNOSUPPORT; goto sock_err; } - + /* TODO */ return recvmsg(__fd, &__msgh, 0); @@ -276,15 +277,15 @@ int sw_close(int __fd) int rc; /* Remove socket from socket management structure. */ - rc = list_remove_socket(__fd); + rc = sm_del(__fd); if (rc < 0) { errno = EBADF; - goto list_unlink_err; + goto del_err; } /* Call classical interface of close(2). */ return close(__fd); -list_unlink_err: +del_err: return -1; } -- 2.20.1