routerinfo.c (3630B)
1 /* Copyright (c) 2001 Matej Pfajfar. 2 * Copyright (c) 2001-2004, Roger Dingledine. 3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 4 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 5 /* See LICENSE for licensing information */ 6 7 /** 8 * @file routerinfo.c 9 * @brief Manipulate full router descriptors. 10 **/ 11 12 #include "core/or/or.h" 13 14 #include "feature/nodelist/nodelist.h" 15 #include "feature/nodelist/routerinfo.h" 16 #include "feature/nodelist/torcert.h" 17 18 #include "feature/nodelist/node_st.h" 19 #include "feature/nodelist/routerinfo_st.h" 20 21 /** Copy the OR port (IP address and TCP port) for <b>router</b> and 22 * <b>family</b> into *<b>ap_out</b>. 23 * 24 * If the requested ORPort does not exist, sets *<b>ap_out</b> to the null 25 * address and port, and returns -1. Otherwise, returns 0. */ 26 int 27 router_get_orport(const routerinfo_t *router, 28 tor_addr_port_t *ap_out, 29 int family) 30 { 31 tor_assert(ap_out != NULL); 32 if (family == AF_INET) { 33 tor_addr_copy(&ap_out->addr, &router->ipv4_addr); 34 ap_out->port = router->ipv4_orport; 35 return 0; 36 } else if (family == AF_INET6) { 37 /* IPv6 addresses are optional, so check if it is valid. */ 38 if (tor_addr_port_is_valid(&router->ipv6_addr, router->ipv6_orport, 0)) { 39 tor_addr_copy(&ap_out->addr, &router->ipv6_addr); 40 ap_out->port = router->ipv6_orport; 41 return 0; 42 } else { 43 tor_addr_port_make_null_ap(ap_out, AF_INET6); 44 return -1; 45 } 46 } else { 47 /* Unsupported address family */ 48 tor_assert_nonfatal_unreached(); 49 tor_addr_port_make_null_ap(ap_out, AF_UNSPEC); 50 return -1; 51 } 52 } 53 54 int 55 router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport) 56 { 57 return 58 (tor_addr_eq(&orport->addr, &router->ipv4_addr) && 59 orport->port == router->ipv4_orport) || 60 (tor_addr_eq(&orport->addr, &router->ipv6_addr) && 61 orport->port == router->ipv6_orport); 62 } 63 64 /** Return a smartlist of tor_addr_port_t's with all the OR ports of 65 <b>ri</b>. Note that freeing of the items in the list as well as 66 the smartlist itself is the callers responsibility. */ 67 smartlist_t * 68 router_get_all_orports(const routerinfo_t *ri) 69 { 70 tor_assert(ri); 71 node_t fake_node; 72 memset(&fake_node, 0, sizeof(fake_node)); 73 /* we don't modify ri, fake_node is passed as a const node_t * 74 */ 75 fake_node.ri = (routerinfo_t *)ri; 76 return node_get_all_orports(&fake_node); 77 } 78 79 /** Return the Ed25519 identity key for this routerinfo, or NULL if it 80 * doesn't have one. */ 81 const ed25519_public_key_t * 82 routerinfo_get_ed25519_id(const routerinfo_t *ri) 83 { 84 if (BUG(! ri)) 85 return NULL; 86 87 const tor_cert_t *cert = ri->cache_info.signing_key_cert; 88 if (cert && ! ed25519_public_key_is_zero(&cert->signing_key)) 89 return &cert->signing_key; 90 else 91 return NULL; 92 } 93 94 /** Given a router purpose, convert it to a string. Don't call this on 95 * ROUTER_PURPOSE_UNKNOWN: The whole point of that value is that we don't 96 * know its string representation. */ 97 const char * 98 router_purpose_to_string(uint8_t p) 99 { 100 switch (p) 101 { 102 case ROUTER_PURPOSE_GENERAL: return "general"; 103 case ROUTER_PURPOSE_BRIDGE: return "bridge"; 104 case ROUTER_PURPOSE_CONTROLLER: return "controller"; 105 default: 106 tor_assert(0); 107 } 108 return NULL; 109 } 110 111 /** Given a string, convert it to a router purpose. */ 112 uint8_t 113 router_purpose_from_string(const char *s) 114 { 115 if (!strcmp(s, "general")) 116 return ROUTER_PURPOSE_GENERAL; 117 else if (!strcmp(s, "bridge")) 118 return ROUTER_PURPOSE_BRIDGE; 119 else if (!strcmp(s, "controller")) 120 return ROUTER_PURPOSE_CONTROLLER; 121 else 122 return ROUTER_PURPOSE_UNKNOWN; 123 }