James Kuszmaul | 82f6c04 | 2021-01-17 11:30:16 -0800 | [diff] [blame^] | 1 | /** |
| 2 | * @file ice.h Internal Interface to ICE |
| 3 | * |
| 4 | * Copyright (C) 2010 Creytiv.com |
| 5 | */ |
| 6 | |
| 7 | |
| 8 | #ifndef RELEASE |
| 9 | #define ICE_TRACE 1 /**< Trace connectivity checks */ |
| 10 | #endif |
| 11 | |
| 12 | |
| 13 | enum ice_checkl_state { |
| 14 | ICE_CHECKLIST_NULL = -1, |
| 15 | ICE_CHECKLIST_RUNNING, |
| 16 | ICE_CHECKLIST_COMPLETED, |
| 17 | ICE_CHECKLIST_FAILED |
| 18 | }; |
| 19 | |
| 20 | enum ice_transp { |
| 21 | ICE_TRANSP_NONE = -1, |
| 22 | ICE_TRANSP_UDP = IPPROTO_UDP |
| 23 | }; |
| 24 | |
| 25 | /** ICE protocol values */ |
| 26 | enum { |
| 27 | ICE_DEFAULT_Tr = 15, /**< Keepalive interval [s] */ |
| 28 | ICE_DEFAULT_Ta_RTP = 20, /**< Pacing interval RTP [ms] */ |
| 29 | ICE_DEFAULT_Ta_NON_RTP = 500, /**< Pacing interval [ms] */ |
| 30 | ICE_DEFAULT_RTO_RTP = 100, /**< Retransmission TimeOut RTP [ms] */ |
| 31 | ICE_DEFAULT_RTO_NONRTP = 500, /**< Retransmission TimeOut [ms] */ |
| 32 | ICE_DEFAULT_RC = 7 /**< Retransmission count */ |
| 33 | }; |
| 34 | |
| 35 | |
| 36 | /** Defines a media-stream component */ |
| 37 | struct icem_comp { |
| 38 | struct le le; /**< Linked-list element */ |
| 39 | struct icem *icem; /**< Parent ICE media */ |
| 40 | struct ice_cand *def_lcand; /**< Default local candidate */ |
| 41 | struct ice_cand *def_rcand; /**< Default remote candidate */ |
| 42 | struct ice_candpair *cp_sel; /**< Selected candidate-pair */ |
| 43 | struct udp_helper *uh; /**< UDP helper */ |
| 44 | void *sock; /**< Transport socket */ |
| 45 | uint16_t lport; /**< Local port number */ |
| 46 | unsigned id; /**< Component ID */ |
| 47 | bool concluded; /**< Concluded flag */ |
| 48 | struct turnc *turnc; /**< TURN Client */ |
| 49 | struct tmr tmr_ka; /**< Keep-alive timer */ |
| 50 | }; |
| 51 | |
| 52 | /** Defines an ICE media-stream */ |
| 53 | struct icem { |
| 54 | struct ice_conf conf; /**< ICE Configuration */ |
| 55 | struct stun *stun; /**< STUN Transport */ |
| 56 | struct sa stun_srv; /**< STUN Server IP address and port */ |
| 57 | struct list lcandl; /**< List of local candidates */ |
| 58 | struct list rcandl; /**< List of remote candidates */ |
| 59 | struct list checkl; /**< Check List of cand pairs (sorted) */ |
| 60 | struct list validl; /**< Valid List of cand pairs (sorted) */ |
| 61 | uint64_t tiebrk; /**< Tie-break value for roleconflict */ |
| 62 | bool mismatch; /**< ICE mismatch flag */ |
| 63 | enum ice_mode lmode; /**< Local mode */ |
| 64 | enum ice_mode rmode; /**< Remote mode */ |
| 65 | enum ice_role lrole; /**< Local role */ |
| 66 | struct tmr tmr_pace; /**< Timer for pacing STUN requests */ |
| 67 | int proto; /**< Transport protocol */ |
| 68 | int layer; /**< Protocol layer */ |
| 69 | enum ice_checkl_state state; /**< State of the checklist */ |
| 70 | struct list compl; /**< ICE media components */ |
| 71 | char *lufrag; /**< Local Username fragment */ |
| 72 | char *lpwd; /**< Local Password */ |
| 73 | char *rufrag; /**< Remote Username fragment */ |
| 74 | char *rpwd; /**< Remote Password */ |
| 75 | ice_connchk_h *chkh; /**< Connectivity check handler */ |
| 76 | void *arg; /**< Handler argument */ |
| 77 | char name[32]; /**< Name of the media stream */ |
| 78 | }; |
| 79 | |
| 80 | /** Defines a candidate */ |
| 81 | struct ice_cand { |
| 82 | struct le le; /**< List element */ |
| 83 | enum ice_cand_type type; /**< Candidate type */ |
| 84 | uint32_t prio; /**< Priority of this candidate */ |
| 85 | char *foundation; /**< Foundation */ |
| 86 | unsigned compid; /**< Component ID (1-256) */ |
| 87 | struct sa rel; /**< Related IP address and port number */ |
| 88 | struct sa addr; /**< Transport address */ |
| 89 | enum ice_transp transp; /**< Transport protocol */ |
| 90 | |
| 91 | /* extra for local */ |
| 92 | struct ice_cand *base; /**< Links to base candidate, if any */ |
| 93 | char *ifname; /**< Network interface, for diagnostics */ |
| 94 | }; |
| 95 | |
| 96 | /** Defines a candidate pair */ |
| 97 | struct ice_candpair { |
| 98 | struct le le; /**< List element */ |
| 99 | struct icem *icem; /**< Pointer to parent ICE media */ |
| 100 | struct icem_comp *comp; /**< Pointer to media-stream component */ |
| 101 | struct ice_cand *lcand; /**< Local candidate */ |
| 102 | struct ice_cand *rcand; /**< Remote candidate */ |
| 103 | bool def; /**< Default flag */ |
| 104 | bool valid; /**< Valid flag */ |
| 105 | bool nominated; /**< Nominated flag */ |
| 106 | enum ice_candpair_state state;/**< Candidate pair state */ |
| 107 | uint64_t pprio; /**< Pair priority */ |
| 108 | struct stun_ctrans *ct_conn; /**< STUN Transaction for conncheck */ |
| 109 | int err; /**< Saved error code, if failed */ |
| 110 | uint16_t scode; /**< Saved STUN code, if failed */ |
| 111 | }; |
| 112 | |
| 113 | |
| 114 | /* cand */ |
| 115 | int icem_lcand_add_base(struct icem *icem, unsigned compid, uint16_t lprio, |
| 116 | const char *ifname, enum ice_transp transp, |
| 117 | const struct sa *addr); |
| 118 | int icem_rcand_add(struct icem *icem, enum ice_cand_type type, unsigned compid, |
| 119 | uint32_t prio, const struct sa *addr, |
| 120 | const struct sa *rel_addr, const struct pl *foundation); |
| 121 | int icem_rcand_add_prflx(struct ice_cand **rcp, struct icem *icem, |
| 122 | unsigned compid, uint32_t prio, |
| 123 | const struct sa *addr); |
| 124 | struct ice_cand *icem_lcand_find_checklist(const struct icem *icem, |
| 125 | unsigned compid); |
| 126 | int icem_cands_debug(struct re_printf *pf, const struct list *lst); |
| 127 | int icem_cand_print(struct re_printf *pf, const struct ice_cand *cand); |
| 128 | |
| 129 | |
| 130 | /* candpair */ |
| 131 | int icem_candpair_alloc(struct ice_candpair **cpp, struct icem *icem, |
| 132 | struct ice_cand *lcand, struct ice_cand *rcand); |
| 133 | int icem_candpair_clone(struct ice_candpair **cpp, struct ice_candpair *cp0, |
| 134 | struct ice_cand *lcand, struct ice_cand *rcand); |
| 135 | void icem_candpair_prio_order(struct list *lst); |
| 136 | void icem_candpair_cancel(struct ice_candpair *cp); |
| 137 | void icem_candpair_make_valid(struct ice_candpair *cp); |
| 138 | void icem_candpair_failed(struct ice_candpair *cp, int err, uint16_t scode); |
| 139 | void icem_candpair_set_state(struct ice_candpair *cp, |
| 140 | enum ice_candpair_state state); |
| 141 | void icem_candpairs_flush(struct list *lst, enum ice_cand_type type, |
| 142 | unsigned compid); |
| 143 | bool icem_candpair_iscompleted(const struct ice_candpair *cp); |
| 144 | bool icem_candpair_cmp(const struct ice_candpair *cp1, |
| 145 | const struct ice_candpair *cp2); |
| 146 | bool icem_candpair_cmp_fnd(const struct ice_candpair *cp1, |
| 147 | const struct ice_candpair *cp2); |
| 148 | struct ice_candpair *icem_candpair_find(const struct list *lst, |
| 149 | const struct ice_cand *lcand, |
| 150 | const struct ice_cand *rcand); |
| 151 | struct ice_candpair *icem_candpair_find_st(const struct list *lst, |
| 152 | unsigned compid, |
| 153 | enum ice_candpair_state state); |
| 154 | struct ice_candpair *icem_candpair_find_compid(const struct list *lst, |
| 155 | unsigned compid); |
| 156 | struct ice_candpair *icem_candpair_find_rcand(struct icem *icem, |
| 157 | const struct ice_cand *rcand); |
| 158 | int icem_candpair_debug(struct re_printf *pf, const struct ice_candpair *cp); |
| 159 | int icem_candpairs_debug(struct re_printf *pf, const struct list *list); |
| 160 | |
| 161 | |
| 162 | /* stun server */ |
| 163 | int icem_stund_recv(struct icem_comp *comp, const struct sa *src, |
| 164 | struct stun_msg *req, size_t presz); |
| 165 | |
| 166 | |
| 167 | /* ICE media */ |
| 168 | void icem_printf(struct icem *icem, const char *fmt, ...); |
| 169 | |
| 170 | |
| 171 | /* Checklist */ |
| 172 | int icem_checklist_form(struct icem *icem); |
| 173 | void icem_checklist_update(struct icem *icem); |
| 174 | |
| 175 | |
| 176 | /* component */ |
| 177 | int icem_comp_alloc(struct icem_comp **cp, struct icem *icem, int id, |
| 178 | void *sock); |
| 179 | int icem_comp_set_default_cand(struct icem_comp *comp); |
| 180 | void icem_comp_set_default_rcand(struct icem_comp *comp, |
| 181 | struct ice_cand *rcand); |
| 182 | void icem_comp_set_selected(struct icem_comp *comp, struct ice_candpair *cp); |
| 183 | struct icem_comp *icem_comp_find(const struct icem *icem, unsigned compid); |
| 184 | void icem_comp_keepalive(struct icem_comp *comp, bool enable); |
| 185 | void icecomp_printf(struct icem_comp *comp, const char *fmt, ...); |
| 186 | int icecomp_debug(struct re_printf *pf, const struct icem_comp *comp); |
| 187 | |
| 188 | |
| 189 | /* conncheck */ |
| 190 | void icem_conncheck_schedule_check(struct icem *icem); |
| 191 | void icem_conncheck_continue(struct icem *icem); |
| 192 | int icem_conncheck_send(struct ice_candpair *cp, bool use_cand, bool trigged); |
| 193 | |
| 194 | |
| 195 | /* icestr */ |
| 196 | const char *ice_mode2name(enum ice_mode mode); |
| 197 | const char *ice_checkl_state2name(enum ice_checkl_state cst); |
| 198 | |
| 199 | |
| 200 | /* util */ |
| 201 | typedef void * (list_unique_h)(struct le *le1, struct le *le2); |
| 202 | |
| 203 | uint64_t ice_calc_pair_prio(uint32_t g, uint32_t d); |
| 204 | void ice_switch_local_role(struct icem *icem); |
| 205 | uint32_t ice_list_unique(struct list *list, list_unique_h *uh); |