#ifndef fooutilshfoo #define fooutilshfoo #include #include #include struct list_head { struct list_head *next; struct list_head *prev; }; #define zmalloc(s) __zmalloc(__func__, __LINE__, s) void *__zmalloc(const char *fn, int line, size_t s); #define xstrdup(s) __xstrdup(__func__, __LINE__, s) char *__xstrdup(const char *fn, int line, const char *s); #define xstrndup(s, n) __xstrndup(__func__, __LINE__, s, n) char *__xstrndup(const char *fn, int line, const char *s, size_t n); #define xfree(s) __xfree(__func__, __LINE__, s) void __xfree(const char *fn, int line, void *ptr); void debug_resource_usage(); #define ADDRSTRLEN (9 /*strlen("AF_INETX ")*/ + INET6_ADDRSTRLEN + 6 /*strlen(" 65535")*/ + 1) struct sockaddr_in46 { union { struct sockaddr_storage storage; struct sockaddr_in in4; struct sockaddr_in6 in6; }; socklen_t addrlen; struct list_head list; }; struct connection { struct sockaddr_in46 remote; char remotestr[ADDRSTRLEN]; struct sockaddr_in46 local; char localstr[ADDRSTRLEN]; struct list_head *addrs; unsigned next_addr; void (*callback)(struct cfg *, struct connection *, int res); }; struct uring_task; void socket_set_low_latency(struct cfg *cfg, int sfd); void connect_any(struct cfg *cfg, struct uring_task *task, struct list_head *addrs, struct connection *conn, void (*callback)(struct cfg *, struct connection *, int res)); uint16_t sockaddr_port(struct sockaddr_in46 *addr); char *sockaddr_to_str(struct sockaddr_in46 *addr, char *buf, size_t buflen); int strtou16_strict(const char *str, uint16_t *result); static inline bool empty_str(const char *str) { if (!str || str[0] == '\0') return true; else return false; } #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) static inline void list_init(struct list_head *list) { list->next = list; list->prev = list; } static inline void list_del(struct list_head *list) { list->next->prev = list->prev; list->prev->next = list->next; } static inline void list_add(struct list_head *new, struct list_head *list) { list->next->prev = new; new->next = list->next; new->prev = list; list->next = new; } static inline void list_replace(struct list_head *old, struct list_head *new) { old->prev->next = new; old->next->prev = new; new->next = old->next; new->prev = old->prev; old->next = old->prev = NULL; } static inline bool list_empty(struct list_head *list) { return list->next == list; } #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) #define list_next_entry(pos, member) \ list_entry((pos)->member.next, typeof(*(pos)), member) #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) #define list_for_each_entry(pos, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member); \ &pos->member != (head); \ pos = list_next_entry(pos, member)) #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member), \ n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) /* #define _cleanup_(x) __attribute__((cleanup(x))) #define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ static inline void func##p(type *p) { \ if (*p) \ func(*p); \ } \ struct __useless_struct_to_allow_trailing_semicolon__ static inline unsigned strv_length(char **strv) { unsigned len; for (len = 0; strv && *strv; strv++) len++; return len; } static inline void strv_free(char **l) { char **k; if (l) { for (k = l; *k; k++) free(k); free(l); } } DEFINE_TRIVIAL_CLEANUP_FUNC(char **, strv_free); #define _cleanup_strv_free_ _cleanup_(strv_freep) static inline void freep(void *p) { free(*(void**) p); } #define _cleanup_free_ _cleanup_(freep) DEFINE_TRIVIAL_CLEANUP_FUNC(int, close); #define _cleanup_close_ _cleanup_(closep) DEFINE_TRIVIAL_CLEANUP_FUNC(FILE *, fclose); #define _cleanup_fclose_ _cleanup_(fclosep) DEFINE_TRIVIAL_CLEANUP_FUNC(DIR *, closedir); #define _cleanup_closedir_ _cleanup_(closedirp) */ #endif