📄 tport.c
字号:
} } return -1;}#else#define tport_try_accept_sigcomp(self, msg) ((void)0)#define tport_canonize_comp(comp) ((void *)0)int tport_can_recv_sigcomp(tport_t const *self){ return 0;}int tport_can_send_sigcomp(tport_t const *self){ return 0;}int tport_has_compression(tport_t const *self, char const *comp){ return 0;}int tport_set_compression(tport_t *self, char const *comp){ return (self == NULL || comp) ? -1 : 0;}#endif/* Define macros for rbtree implementation */#define TP_LEFT(tp) ((tp)->tp_left)#define TP_RIGHT(tp) ((tp)->tp_right)#define TP_PARENT(tp) ((tp)->tp_dad)#define TP_SET_RED(tp) ((tp)->tp_black = 0)#define TP_SET_BLACK(tp) ((tp)->tp_black = 1)#define TP_IS_RED(tp) ((tp) && (tp)->tp_black == 0)#define TP_IS_BLACK(tp) (!(tp) || (tp)->tp_black == 1)#define TP_COPY_COLOR(dst, src) ((dst)->tp_black = (src)->tp_black)#define TP_INSERT(tp) ((void)0)#define TP_REMOVE(tp) ((tp)->tp_left = (tp)->tp_right = (tp)->tp_dad = NULL)static inline int tp_cmp(tport_t const *a, tport_t const *b){ if (a == b) return 0; if (a->tp_addrlen != b->tp_addrlen) return a->tp_addrlen - b->tp_addrlen; return memcmp(a->tp_addr, b->tp_addr, sizeof(a->tp_addr));}static inline int tprb_is_inserted(tport_t const *a){ return a->tp_dad != 0 || a->tp_left != 0 || a->tp_right != 0;}RBTREE_PROTOS(static inline, tprb, tport_t);RBTREE_BODIES(static inline, tprb, tport_t, TP_LEFT, TP_RIGHT, TP_PARENT, TP_IS_RED, TP_SET_RED, TP_IS_BLACK, TP_SET_BLACK, TP_COPY_COLOR, tp_cmp, TP_INSERT, TP_REMOVE);enum { /** Default per-thread read queue length */ THRP_PENDING = 8};struct tport_pending_s { // tport_pending_t *p_left, *p_right, *p_parent; void *p_client; tport_pending_error_f *p_callback; msg_t *p_msg; int p_reported;};/** Return true if transport is master. */inline int tport_is_master(tport_t const *self){ return self && self->tp_master->mr_master == self;}/** Return true if transport is primary. */inline int tport_is_primary(tport_t const *self){ return self && self->tp_pri->pri_primary == self;}/** Return true if transport is secondary. */inline int tport_is_secondary(tport_t const *self){ return self && self->tp_master->mr_master != self && self->tp_pri->pri_primary != self;}/** Test if transport has been registered */static inline int tport_is_registered(tport_t const *self){ return self->tp_index != 0;}/** Test if transport is stream. */inline int tport_is_stream(tport_t const *self){ return self->tp_pri->pri_socktype == SOCK_STREAM;} /** Test if transport is dgram. */static inline int tport_is_dgram(tport_t const *self){ return self->tp_pri->pri_socktype == SOCK_DGRAM;} /** Test if transport is udp. */inline int tport_is_udp(tport_t const *self){ return self->tp_pri->pri_protocol == IPPROTO_UDP;} /** Test if transport is tcp. */inline int tport_is_tcp(tport_t const *self){ return self->tp_pri->pri_protocol == IPPROTO_TCP;} /** Test if transport is needs connect() before sending. */static inline int tport_is_connection_oriented(tport_t const *self){ return self->tp_conn_orient;}/** Test if transport has actual connection. */static inline int tport_is_connected(tport_t const *self){ return self->tp_connected;}/** Return 1 if transport is reliable, 0 otherwise. * * (Note that this is part of external API). */int tport_is_reliable(tport_t const *self){ return self != NULL && (self->tp_pri->pri_socktype == SOCK_STREAM || self->tp_pri->pri_socktype == SOCK_SEQPACKET);}/** Return true if transport supports IPv4 */int tport_has_ip4(tport_t const *self){ return self && (self->tp_pri->pri_family == 0 || self->tp_pri->pri_family == AF_INET /* || self->tp_pri->pri_family2 == AF_INET */);}#if SU_HAVE_IN6/** Return true if transport supports IPv6 */int tport_has_ip6(tport_t const *self){ return self && (self->tp_pri->pri_family == 0 || self->tp_pri->pri_family == AF_INET6);}#endif/** Return true if transport supports TLS. */int tport_has_tls(tport_t const *self){#if HAVE_TLS return self && self->tp_tls != NULL;#else return 0;#endif }/** Test if transport has been closed */static inline int tport_is_closed(tport_t const *self){ return self->tp_closed;}/** Test if transport has been shut down */static inline int tport_is_shutdown(tport_t const *self){ return self->tp_closed || self->tp_send_close || self->tp_recv_close;}/** Test if transport is bound */static inline int tport_is_bound(tport_t const *self){ return self->tp_protoname != NULL;}/** MTU for transport */static inline unsigned tport_mtu(tport_t const *self){ return self->tp_params->tpp_mtu;}static inlineint tport_has_sigcomp(tport_t const *self){ return self->tp_name->tpn_comp != NULL;}staticint tport_events(tport_t const *self){ int events = self->tp_events;#if HAVE_TLS if (self->tp_tls) { events = tls_events(self->tp_tls, events); SU_DEBUG_7(("tport_events(%p): logical events%s%s%s%s real%s%s%s%s\n", self, (self->tp_events & SU_WAIT_IN) ? " IN" : "", (self->tp_events & SU_WAIT_OUT) ? " OUT" : "", (self->tp_events & SU_WAIT_HUP) ? " HUP" : "", (self->tp_events & SU_WAIT_ERR) ? " ERR" : "", (events & SU_WAIT_IN) ? " IN" : "", (events & SU_WAIT_OUT) ? " OUT" : "", (events & SU_WAIT_HUP) ? " HUP" : "", (events & SU_WAIT_ERR) ? " ERR" : "")); } else#endif SU_DEBUG_7(("tport_events(%p): events%s%s%s%s\n", self, (events & SU_WAIT_IN) ? " IN" : "", (events & SU_WAIT_OUT) ? " OUT" : "", (events & SU_WAIT_HUP) ? " HUP" : "", (events & SU_WAIT_ERR) ? " ERR" : "")); return su_root_eventmask(self->tp_master->mr_root, self->tp_index, self->tp_socket, events);}/* NAT things */staticstruct tport_nat_s *tport_nat_initialize_nat_traversal(tport_master_t *mr, tp_name_t const *tpn, char const * const **return_transports, tagi_t const *tags);staticchar *tport_nat_get_external_ip_address(struct tport_nat_s *nat);#if HAVE_SOFIA_STUNstaticint tport_nat_stun_bind(struct tport_nat_s *nat, su_sockaddr_t su[1], socklen_t *sulen, su_socket_t s);#endifstaticint tport_nat_traverse_nat(tport_master_t *, su_sockaddr_t su[1], su_addrinfo_t const *ai, su_socket_t s);staticint tport_nat_set_canon(tport_t *self, struct tport_nat_s *nat);staticint tport_nat_finish(tport_primary_t *self);#define PASSIVE PASSIVE#define ACTIVE ACTIVEenum socket_open { PASSIVE = 0, ACTIVE = 1 };static tport_t *tport_connect(tport_primary_t *pri, su_addrinfo_t *ai, tp_name_t const *tpn);static int tport_get_local_addrinfo(tport_master_t *mr, su_localinfo_t *li, char const *port, su_addrinfo_t const *hints, su_addrinfo_t **return_ai);static void tport_freeaddrinfo(tport_master_t *mr, su_addrinfo_t *ai);#if HAVE_TLSstatic tls_t *tport_init_tls(tagi_t *tags);#endifstatic int tport_bind_client(tport_master_t *self, tp_name_t const *tpn, char const * const transports[], tagi_t *tags), tport_bind_server(tport_master_t *, tp_name_t const *tpn, char const * const transports[], tagi_t *tags), tport_init_compression(tport_primary_t *self, char const *compression, tagi_t *tl), tport_setname(tport_t *, char const *, su_sockaddr_t const *, char const *), tport_recv(su_root_magic_t *m, su_wait_t *w, tport_t *self), tport_accept(su_root_magic_t *m, su_wait_t *w, tport_t *self), tport_connected(su_root_magic_t *m, su_wait_t *w, tport_t *self), tport_resolve(tport_t *self, msg_t *msg, tp_name_t const *tpn), tport_send_msg(tport_t *, msg_t *, tp_name_t const *tpn, struct sigcomp_compartment *cc), tport_vsend(tport_t *self, msg_t *msg, tp_name_t const *tpn, msg_iovec_t iov[], int iovused, struct sigcomp_compartment *cc), tport_vsend_iovec(tport_t const *, msg_t *, msg_iovec_t iov[], int iovused), tport_send_error(tport_t *, msg_t *, tp_name_t const *, char const *comp), tport_queue(tport_t *self, msg_t *msg), tport_queue_rest(tport_t *self, msg_t *msg, msg_iovec_t iov[], int iovused), tport_pending_error(tport_t *self, su_sockaddr_t const *dst, int error), tport_pending_errmsg(tport_t *self, msg_t *msg, int error), tport_launch_threadpool(tport_primary_t *pri), tport_kill_threadpool(tport_primary_t *pri), tport_thread_send(tport_t *, struct sigcomp_compartment *, msg_t *, unsigned mtu);tport_t *tport_by_addrinfo(tport_primary_t const *pri, su_addrinfo_t const *ai, tp_name_t const *tpn);void tport_peer_address(tport_t *self, msg_t *msg);static unsigned long tport_now(void);static void tport_tick(su_root_magic_t *, su_timer_t *, tport_master_t *mr);#if HAVE_TLSstatic int tport_tls_event(tport_t *self, int events), tport_tls_writevec(tport_t *self, msg_iovec_t iov[], int iovlen);#endif#if HAVE_SIGCOMPstatic int tport_sigcomp_vsend(tport_t const *self, msg_t *msg, msg_iovec_t iov[], int iovused, struct sigcomp_compartment *cc, tport_sigcomp_t *sc);#endif static void tport_error_event(tport_t *self, int events), tport_send_event(tport_t *self, int events), tport_hup_event(tport_t *self, int events), tport_recv_event(tport_t *self, int events);static void tport_parse(tport_t *self, int complete, su_time_t now);static void tport_deliver(tport_t *, msg_t *msg, msg_t *next, struct sigcomp_udvm **udvm, su_time_t now);static tport_primary_t *tport_alloc_primary(tport_master_t *tpm);static tport_primary_t *tport_listen(tport_master_t *mr, su_addrinfo_t const *ai, char const *canon, char const *protoname, int port, tagi_t *tags);static void tport_zap_primary(tport_primary_t *);static tport_t *tport_alloc_secondary(tport_primary_t *pri);static void tport_zap_secondary(tport_t *);static void tport_close(tport_t *self);static void tport_open_log(tport_master_t *mr, tagi_t *tags);static void tport_dump_iovec(tport_t const *self, msg_t *msg, int n, su_iovec_t const iov[], int iovused, char const *what, char const *how);static void tport_log_msg(tport_t *tp, msg_t *msg, char const *what, char const *via, char const *indent, su_time_t now);static void tport_stamp(tport_t const *tp, msg_t *msg, char stamp[128], char const *what, int n, char const *via, su_time_t now);static char *localipname(int pf, char *buf, int bufsiz);static void tport_error_report(tport_t *self, int errcode, su_sockaddr_t const *dst);static int getprotohints(su_addrinfo_t *hints, char const *proto, int flags);static void tport_send_queue(tport_t *self);/* Stack class used when transports are being destroyed */staticvoid tport_destroy_recv(tp_stack_t *stack, tport_t *tp, msg_t *msg, tp_magic_t *magic, su_time_t received){ msg_destroy(msg);}staticvoid tport_destroy_error(tp_stack_t *stack, tport_t *tp, int errcode, char const *remote){}staticmsg_t *tport_destroy_alloc(tp_stack_t *stack, int flags, char const data[], unsigned len, tport_t const *tp, tp_client_t *tpc){ return NULL;}/**@var TPORT_LOG * * Environment variable determining if parsed message contents are logged. * * If the TPORT_LOG environment variable is set, the tport module logs the * contents of parsed messages. This eases debugging the signaling greatly. * * @sa TPORT_DUMP, TPORT_DEBUG, tport_log */extern char const TPORT_LOG[]; /* dummy declaration for Doxygen *//**@var TPORT_DUMP * * Environment variable for transport data dump. * * The received and sent data is dumped to the file specified by TPORT_DUMP * environment variable. This can be used to save message traces and help * hairy debugging tasks. * * @sa TPORT_LOG, TPORT_DEBUG, tport_log */extern char const TPORT_DUMP[]; /* dummy declaration for Doxygen *//**@var TPORT_DEBUG * * Environment variable determining the debug log level for @b tport module. * * The TPORT_DEBUG environment variable is used to determine the debug logging * level for @b tport module. The default level is 3. * * @sa <su_debug.h>, tport_log, SOFIA_DEBUG */extern char const TPORT_DEBUG[]; /* dummy declaration for Doxygen *//**Debug log for @b tport module. * * The tport_log is the log object used by @b tport module. The level of * #tport_log is set using #TPORT_DEBUG environment variable. */su_log_t tport_log[] = { SU_LOG_INIT("tport", "TPORT_DEBUG", SU_DEBUG)};/** Name for "any" transport. @internal */static char const tpn_any[] = "*";/** Create the master transport. @deprecated Use tport_tcreate(). */tport_t *tport_create(tp_stack_t *stack, tp_stack_class_t const *tpac, su_root_t *root){ return tport_tcreate(stack, tpac, root, TAG_END());}/** Create the master transport. */tport_t *tport_tcreate(tp_stack_t *stack, tp_stack_class_t const *tpac, su_root_t *root, tag_type_t tag, tag_value_t value, ...){ tport_master_t *mr; tp_name_t *tpn; tport_params_t *tpp; unsigned tick; ta_list ta; if (!stack || !tpac || !root) { su_seterrno(EINVAL); return NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -