X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=blobdiff_plain;f=src%2Fraw%2Fswift_list.c;h=04832ac78a5a65bc160de6e77ef7ecd3e9370f78;hb=bf58ee2adc522ea0dbd050d94d3625071eb02d1b;hp=d35984551c6946f0a4911e532367f032b2fbbd59;hpb=b0714e2b62a1b0b3b9d716a6431018dd56f1bae0;p=swifty.git 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; }