/* Профиль конкретного endpoint: изменение адреса и доступность входа независимы. * checked_at — время измерения владельца в Unix microseconds, не версия NODEINFO. * Профиль помогает выбирать попытки; работоспособность подтверждает транспорт. */ #ifndef ADDRESS_PROFILE_H #define ADDRESS_PROFILE_H #include enum address_mapping { ADDRESS_MAP_UNKNOWN, ADDRESS_MAP_UNCHANGED, ADDRESS_MAP_EIM, ADDRESS_MAP_DEPENDENT }; enum address_inbound { ADDRESS_IN_UNKNOWN, ADDRESS_IN_OPEN, ADDRESS_IN_CONTACT }; enum address_profile_source { ADDRESS_SOURCE_NONE, ADDRESS_SOURCE_ETCP, ADDRESS_SOURCE_STUN }; #define ADDRESS_PROFILE_TTL_US UINT64_C(300000000) struct address_profile { uint8_t mapping; uint8_t inbound; uint8_t source; /* ETCP — этот endpoint; STUN — резервная оценка его IP/netif. */ uint64_t evidence_id; uint64_t checked_at; }; static inline const char *address_mapping_name(uint8_t value) { static const char *const names[] = {"UNKNOWN", "UNCHANGED", "EIM", "DEPENDENT"}; return value <= ADDRESS_MAP_DEPENDENT ? names[value] : "INVALID"; } static inline const char *address_inbound_name(uint8_t value) { static const char *const names[] = {"UNKNOWN", "OPEN", "CONTACT_REQUIRED"}; return value <= ADDRESS_IN_CONTACT ? names[value] : "INVALID"; } static inline const char *address_profile_source_name(uint8_t value) { static const char *const names[] = {"NONE", "ETCP", "STUN"}; return value <= ADDRESS_SOURCE_STUN ? names[value] : "INVALID"; } static inline int address_profile_valid(const struct address_profile *profile) { return profile && profile->mapping <= ADDRESS_MAP_DEPENDENT && profile->inbound <= ADDRESS_IN_CONTACT && profile->source <= ADDRESS_SOURCE_STUN && ((!profile->mapping && !profile->inbound && profile->source == ADDRESS_SOURCE_NONE) || ((profile->mapping || profile->inbound) && profile->source && profile->evidence_id && profile->checked_at)); } static inline int address_profile_fresh(const struct address_profile *profile, uint64_t now_us) { return profile && profile->evidence_id && profile->checked_at && now_us >= profile->checked_at && now_us - profile->checked_at <= ADDRESS_PROFILE_TTL_US; } #endif