NSIS-ka
A free C++ implementation of NSIS protocols

Changeset 4211


Ignore:
Timestamp:
Aug 6, 2009, 2:21:51 PM (8 years ago)
Author:
stud-lenk
Message:

Re-sync with trunk (r4210)

Location:
protlib/branches/20090723-multicast
Files:
24 edited
9 copied

Legend:

Unmodified
Added
Removed
  • protlib/branches/20090723-multicast

  • protlib/branches/20090723-multicast/include/address.h

    r4158 r4211  
    195195        /// clear IP buffer (sets IP address to undefined/any and deletes any outstring)
    196196        void clear_ip();
     197
     198        struct ltaddr {
     199                inline bool operator()(const hostaddress *a,
     200                    const hostaddress *b) const {
     201                        if (a->ipv4flag != b->ipv4flag)
     202                                return a->ipv4flag;
     203                        if (a->ipv4flag)
     204                                return (memcmp(&a->ipv4addr, &b->ipv4addr,
     205                                    sizeof(a->ipv4addr)) < 0);
     206                        else
     207                                return (memcmp(&a->ipv6addr, &b->ipv6addr,
     208                                    sizeof(a->ipv6addr)) < 0);
     209                }
     210        };
    197211private:
    198212        /// pointer to IP string representation
     
    758772}; // end udsaddress
    759773
    760 template <typename _dT>
    761 class RadixTrie {
    762 public:
    763         typedef _dT     data_type;
    764 
    765         struct node {
    766                 node(netaddress *k, data_type *d) : key(k), data(d) {
    767                         left = right = this;
    768                         index = 0;
    769                 }
    770                 ~node() {
    771                         if (data)
    772                                 delete data;
    773                         if (key)
    774                                 delete key;
    775                         if (left != 0 && left->index > index)
    776                                 delete left;
    777                         if (right != 0 && right->index > index)
    778                                 delete right;
    779                 }
    780                 node                    *left;
    781                 node                    *right;
    782                 netaddress              *key;
    783                 data_type               *data;
    784                 int                      index;
    785         };
    786 
    787         RadixTrie() {
    788                 netaddress *def;
    789                 def = new netaddress("0.0.0.0", (prefix_length_t)0);
    790                 v4head = new node(def, 0);
    791                 def = new netaddress("::", (prefix_length_t)0);
    792                 v6head = new node(def, 0);
    793         }
    794 
    795         ~RadixTrie() {
    796                 delete v4head;
    797                 delete v6head;
    798         }
    799 
    800         node *insert(netaddress &key, data_type &dat) {
    801                 node *a, *b, *c, *n, *m;
    802                 int cmp, pos = 0;
    803 
    804                 c = a = key.is_ipv4() ? v4head : v6head;
    805 
    806                 // search the tree as long as there are bits left in key
    807                 while (key.get_pref_len() > a->index) {
    808 
    809                         // compare key to key in node a from position a->index
    810                         pos = a->index - 1;
    811                         cmp = key.rdx_cmp(a->key, &pos);
    812                         if (pos < 0)
    813                                 abort();
    814 
    815                         // in case of a perfect match
    816                         if ((cmp == 0) &&
    817                             (a->key->get_pref_len() == key.get_pref_len())) {
    818                             // replace data in node
    819                                 if (a->data)
    820                                         delete a->data;
    821                                 a->data = &dat;
    822                                 return a;
    823                         }
    824 
    825                         if (cmp == 0)
    826                                 break;
    827 
    828                         // select node to continue the search based on the
    829                         // first different bit between a and key
    830                         b = cmp < 0 ? a->left : a->right;
    831 
    832                         // we reached a dead end
    833                         if (b->index <= a->index)
    834                                 break;
    835 
    836                         // the first difference was before a's bitmask ended
    837                         // we must not make any more progress
    838                         if (pos <= a->key->get_pref_len())
    839                                 break;
    840 
    841                         c = a;
    842                         a = b;
    843                 }
    844 
    845                 // first check if a and key share a common prefix
    846                 if ((key.get_pref_len() == a->key->get_pref_len()) ||
    847                    (pos > a->index && pos <= a->key->get_pref_len())) {
    848                         int opos = pos;
    849 
    850                         // make sure we didn't just miss the perfect match
    851                         pos = a->index;
    852                         cmp = key.rdx_cmp(a->key, &pos);
    853                         if (cmp == 0 &&
    854                             (a->key->get_pref_len() == key.get_pref_len())) {
    855                             // replace data in node
    856                                 if (a->data)
    857                                         delete a->data;
    858                                 a->data = &dat;
    859                                 return a;
    860                         }
    861 
    862                         // create a node with that prefix
    863                         pos = opos;
    864                         n = new node(new netaddress(key), 0);
    865                         n->key->set_pref_len(pos - 1);
    866 
    867                         // hook it to the previous node(c)
    868                         pos = c->index;
    869                         cmp = n->key->rdx_cmp(c->key, &pos);
    870                         n->index = pos;
    871                         if (n->index <= c->index) {
    872                                 cout << "DEAD NODE INSERTION!!!" << endl;
    873                                 abort();
    874                         }
    875                         if (cmp < 0) {
    876                                 if (c->left != a) {
    877                                         cout << "TREE CORRUPTION!!!" << endl;
    878                                         abort();
    879                                 }
    880                                 c->left = n;
    881                         } else {
    882                                 if (c->right != a) {
    883                                         cout << "TREE CORRUPTION!!!" << endl;
    884                                         abort();
    885                                 }
    886                                 c->right = n;
    887                         }
    888 
    889                         // hook the current node(a) to the common prefix
    890                         // node(n)
    891                         pos = n->index;
    892                         cmp = a->key->rdx_cmp(n->key, &pos);
    893                         a->index = pos;
    894                         if (a->index <= n->index) {
    895                                 cout << "DEAD NODE INSERTION!!!" << endl;
    896                                 abort();
    897                         }
    898                         if (cmp < 0)
    899                                 n->left = a;
    900                         else
    901                                 n->right = a;
    902 
    903                         // create a new node(m) for the insert
    904                         m = new node(new netaddress(key), &dat);                       
    905                         // hook node(m) to the common prefix node(n)
    906                         pos = n->index;
    907                         cmp = m->key->rdx_cmp(n->key, &pos);
    908                         m->index = pos;
    909                         if (cmp < 0) {
    910                                 if (n->left == a) {
    911                                         cout << "OVERWRITE!!!" << endl;
    912                                         abort();
    913                                 }
    914                                 n->left = m;
    915                         } else {
    916                                 if (n->right == a) {
    917                                         cout << "OVERWRITE!!!" << endl;
    918                                         abort();
    919                                 }
    920                                 n->right = m;
    921                         }
    922 
    923                         return m;
    924                 }
    925 
    926                 // c is a prefix of key, key is a prefix of a
    927                 if (a->index >= pos) {
    928                         // create a new node for the key
    929                         n = new node(new netaddress(key), &dat);
    930                         // hook it to the previous node(c)
    931                         n->index = pos;
    932                         if (n->index <= c->index) {
    933                                 cout << "DEAD NODE INSERTION!!!" << endl;
    934                                 abort();
    935                         }
    936                         if (cmp < 0) {
    937                                 if (c->left != a) {
    938                                         cout << "TREE CORRUPTION!!!" << endl;
    939                                         abort();
    940                                 }
    941                                 c->left = n;
    942                         } else {
    943                                 if (c->right != a) {
    944                                         cout << "TREE CORRUPTION!!!" << endl;
    945                                         abort();
    946                                 }
    947                                 c->right = n;
    948                         }
    949 
    950                         // hook the current node(a) to the newly created
    951                         // node(n)
    952                         pos = n->index;
    953                         cmp = a->key->rdx_cmp(n->key, &pos);
    954                         a->index = pos;
    955                         if (a->index <= c->index) {
    956                                 cout << "DEAD NODE INSERTION!!!" << endl;
    957                                 abort();
    958                         }
    959                         if (cmp < 0)
    960                                 n->left = a;
    961                         else
    962                                 n->right = a;
    963 
    964                         return n;
    965                 }
    966 
    967                 // reached a deadend, simply add a new node
    968                 n = new node(new netaddress(key), &dat);
    969                 n->index = pos;
    970                 if (n->index <= a->index) {
    971                         cout << "DEAD NODE INSERTION!!!" << endl;
    972                         abort();
    973                 }
    974                 if (b->index <= a->index) {
    975                         if (cmp < 0)
    976                                 a->left = n;
    977                         else
    978                                 a->right = n;
    979                 } else {
    980                         cout << "TREE CORRUPTION!!!" << endl;
    981                         abort();
    982                 }
    983 
    984                 return n;
    985         }
    986 
    987         node *lookup_node(netaddress &key, bool lpfm = true,
    988             bool with_data = true) {
    989                 node *a, *b, *c, *lpfn;
    990                 int cmp, pos = 0;
    991 
    992                 lpfn = 0;
    993                 c = b = a = key.is_ipv4() ? v4head : v6head;
    994                 if (lpfm) {
    995                         if (!with_data)
    996                                 lpfn = a;
    997                         else if (a->data)
    998                                 lpfn = a;
    999                 }
    1000 
    1001                 // search the tree as long as there are bits left in key
    1002                 while (key.get_pref_len() > a->index) {
    1003 
    1004                         // compare key to key in node a from pos
    1005                         pos--;
    1006                         cmp = key.rdx_cmp(a->key, &pos);
    1007 
    1008                         // all of key consumed
    1009                         if (cmp == 0) {
    1010                                 // key is less specific than a
    1011                                 if (key.get_pref_len() <
    1012                                     a->key->get_pref_len())
    1013                                         return lpfm ? lpfn : NULL;
    1014                                
    1015                                 // key is an exact match for a
    1016                                 if (key.get_pref_len() >=
    1017                                     a->key->get_pref_len()) {
    1018                                         if (!with_data)
    1019                                                 return a;
    1020                                         if (a->data)
    1021                                                 return a;
    1022                                         return lpfm ? lpfn : NULL;
    1023                                 }
    1024                         }
    1025 
    1026                         // all of a consumed -> a is a prefix of key
    1027                         if (pos > a->key->get_pref_len()) {
    1028                                 if (!with_data)
    1029                                         lpfn = a;
    1030                                 else if (a->data)
    1031                                         lpfn = a;
    1032                         }
    1033 
    1034                         // select node to continue the search based on the
    1035                         // first different bit between a and key
    1036                         b = cmp < 0 ? a->left : a->right;
    1037 
    1038                         // we reached a dead end
    1039                         if (b->index <= a->index)
    1040                                 break;
    1041 
    1042                         c = a;
    1043                         a = b;
    1044                 }
    1045 
    1046                 return lpfm ? lpfn : NULL;
    1047         }
    1048 
    1049         data_type *lookup(netaddress &key, bool lpfm = true) {
    1050                 node *n = lookup_node(key, lpfm);
    1051 
    1052                 return n ? n->data : NULL;
    1053         }
    1054 
    1055         bool remove(netaddress &key) {
    1056                 node *n = lookup_node(key);
    1057 
    1058                 if (n && n->data) {
    1059                         delete n->data;
    1060                         n->data = NULL;
    1061                 }
    1062 
    1063                 return (n != 0);
    1064         }
    1065 
    1066         bool remove_all(netaddress &key) {
    1067                 node *n = lookup_node(key, false, false);
    1068 
    1069                 if (n == 0)
    1070                         return false;
    1071 
    1072                 if (n->data) {
    1073                         delete n->data;
    1074                         n->data = NULL;
    1075                 }
    1076 
    1077                 if (n->left->index > n->index) {
    1078                         delete n->left;
    1079                         n->left = n;
    1080                 }
    1081                 if (n->right->index > n->index) {
    1082                         delete n->right;
    1083                         n->right = n;
    1084                 }
    1085 
    1086                 return true;
    1087         }
    1088 
    1089         void print() {
    1090                 cout << "v4_TREE: " << endl;
    1091                 print_node(v4head);
    1092                 cout << "v6_TREE: " << endl;
    1093                 print_node(v6head);
    1094         }
    1095 
    1096         void print_node(node *x, bool decent = true) {
    1097                 if (x && x->key) {
    1098                         cout << "node: " << x << " key: " <<  *x->key;
    1099                         if (x->data != 0)
    1100                                 cout << " data: " << x->data;
    1101                         else
    1102                                 cout << " data: NULL";
    1103                         cout << " index: " << x->index << endl;
    1104                         cout << "\tleft: " << x->left << " right: " << x->right << endl;
    1105                         if (decent) {
    1106                                 if (x->left->index > x->index)
    1107                                         print_node(x->left);
    1108                                 if (x->right->index > x->index)
    1109                                         print_node(x->right);
    1110                         }
    1111                 }
    1112         }
    1113 
    1114 private:
    1115         struct node *v4head;
    1116         struct node *v6head;
    1117 };
    1118774
    1119775
    1120776ostream& operator<<(ostream& outstream, const list<hostaddress>& addresslist);
    1121777
    1122 /*
    1123  * AddressList
    1124  */
    1125 
    1126 class AddressList {
    1127 public:
    1128         class AddrProperty {
    1129                 public:
    1130                         AddrProperty(const char *name) {
    1131                                 pname = new string(name);
    1132                         }
    1133                         ~AddrProperty() {
    1134                                 delete pname;
    1135                         };
    1136 
    1137                         string *pname;
    1138         };
    1139 
    1140         // Default properties, N.B. Ignore will remove all other properties
    1141         static AddrProperty *LocalAddr_P;
    1142         static AddrProperty *ConfiguredAddr_P;
    1143 
    1144 private:
    1145         // This is special
    1146         static AddrProperty *IgnoreAddr_P;
    1147         static AddrProperty *AnyAddr_P;
    1148 
    1149 public:
    1150         struct ltstr {
    1151                 bool operator()(const char* s1, const char* s2) const
    1152                 { return strcmp(s1, s2) < 0; }
    1153         };
    1154         struct ltna {
    1155                 bool operator()(const netaddress &s1, const netaddress &s2)
    1156                     const {
    1157                         if (s1.is_ipv4() != s2.is_ipv4())
    1158                                 return (s1.is_ipv4());
    1159                         int cmp, pos = 0;
    1160                         cmp = s1.rdx_cmp(&s2, &pos);
    1161                         return (cmp < 0);
    1162                 }
    1163                
    1164         };
    1165         typedef set<char *, ltstr>      iflist_t;
    1166         typedef set<netaddress, ltna>   addrlist_t;
    1167 
    1168         AddressList();
    1169         ~AddressList();
    1170 
    1171         // Configure by interfaces
    1172         // Return a list of all local interfaces, which are monitored
    1173         iflist_t *get_interfaces();
    1174         // Begin interface list (otherwise the following have no effect)
    1175         // If start_empty is true use an empty list, otherwise add all
    1176         // currently configured interfaces
    1177         bool by_interface(bool start_empty = true);
    1178         // Add interface to monitoring
    1179         bool add_interface(char *name);
    1180         // Remove interface from monitoring
    1181         bool del_interface(char *name);
    1182 
    1183         // Manage properties
    1184         // If 'all' is true operate on all matching addresses as well
    1185         bool add_property(netaddress &na, AddrProperty *p = ConfiguredAddr_P,
    1186             bool propagate = true);
    1187         bool del_property(netaddress &na, AddrProperty *p = ConfiguredAddr_P,
    1188             bool propagate = true);
    1189         inline bool purge_properties(netaddress &na, bool prop = true) {
    1190                 return del_property(na, AnyAddr_P, prop);
    1191         };
    1192         bool add_host_prop(const char *name, AddrProperty *p = ConfiguredAddr_P);
    1193         bool del_host_prop(const char *name, AddrProperty *p = ConfiguredAddr_P);
    1194         inline bool purge_host_prop(const char *name) {
    1195                 return del_host_prop(name, AnyAddr_P);
    1196         }
    1197 
    1198         // Special property
    1199         bool ignore(netaddress &na, bool propagate = true);
    1200         bool unignore(netaddress &na, bool propagate = true);
    1201         bool ignore_bogons(void);
    1202         bool ignore_locals(void);
    1203         bool ignore_loopback(void);
    1204        
    1205         // Check if the given address has the given property
    1206         bool addr_is(netaddress &na, AddrProperty *prop);
    1207         bool addr_is(const hostaddress &ha, AddrProperty *prop) {
    1208                 netaddress na(ha);
    1209                 return addr_is(na, prop);
    1210         }
    1211         // Check if the given address is in a network with the given property
    1212         bool addr_is_in(netaddress &na, AddrProperty *prop);
    1213         bool addr_is_in(const hostaddress &ha, AddrProperty *prop) {
    1214                 netaddress na(ha);
    1215                 return addr_is_in(na, prop);
    1216         }
    1217 
    1218         addrlist_t *get_addrs(AddrProperty *prop = LocalAddr_P);
    1219         netaddress *get_first(AddrProperty *p = LocalAddr_P, bool IPv4 = true);
    1220 
    1221         netaddress *get_src_addr(const netaddress &dest, uint32_t *prefs);
    1222 private:
    1223         typedef map<AddrProperty *, bool>       propmap_t;
    1224         typedef RadixTrie<propmap_t>            addr2prop_t;
    1225 
    1226         iflist_t *interfaces;
    1227         addr2prop_t prop_trie;
    1228 
    1229         // Backends for public functions
    1230         void getifaddrs_iflist(iflist_t &list);
    1231         bool getifaddrs_is_local(netaddress &na);
    1232         void getifaddrs_get_addrs(addrlist_t &list);
    1233 
    1234         void bequeath(addr2prop_t::node *head, AddrProperty *p,
    1235             bool add = true);
    1236         void collect(addr2prop_t::node *head, AddrProperty *p,
    1237             addrlist_t &list);
    1238         addr2prop_t::node *collect_first(addr2prop_t::node *head,
    1239             AddrProperty *p);
    1240 };
    1241 
    1242 inline ostream &operator<<(ostream &out, const AddressList::AddrProperty &prop) {
    1243         return out << *prop.pname;
    1244 }
    1245778
    1246779
  • protlib/branches/20090723-multicast/include/configpar.h

    r4163 r4211  
    181181 *
    182182 **/
    183 template <class T> class configpar : public configparBase
     183template <typename T> class configpar : public configparBase
    184184{
    185185public:
    186186  configpar<T>(const T& default_value) : configparBase(), value(default_value) {};
    187         configpar<T>(realm_id_t realm, configpar_id_t configparid, const char* name, const char* description, bool changeable_while_running, const T& default_value, const char* unitinfo= NULL) : configparBase(realm, configparid, name, description, changeable_while_running, unitinfo), value(default_value) {};
     187  configpar<T>(realm_id_t realm, configpar_id_t configparid, const char* name, const char* description, bool changeable_while_running, const T& default_value= T(), const char* unitinfo= NULL) : configparBase(realm, configparid, name, description, changeable_while_running, unitinfo), value(default_value) {};
    188188
    189189  T getPar() const throw() { return value; }
     
    224224
    225225// use the default output operator for this type
    226 template<class T>
     226template<typename T>
    227227inline
    228228ostream&
     
    233233
    234234// use the default input operator for this type
    235 template<class T>
     235template<typename T>
    236236inline
    237237istream&
     
    242242
    243243
    244 template<class T>
     244template<typename T>
    245245inline
    246246ostream&
     
    251251
    252252
    253 template<class T>
     253template<typename T>
    254254inline
    255255istream&
     
    260260
    261261
    262 template<class T>
     262template<typename T>
    263263inline
    264264ostream&
     
    270270
    271271
    272 template<class T>
     272template<typename T>
    273273inline
    274274istream&
  • protlib/branches/20090723-multicast/include/messages.h

    r3675 r4211  
    6767                type_info,
    6868                type_routing,
    69                 type_API
     69                type_API,
     70                type_mobility
    7071        }; // end type_t
    7172
     
    107108                qaddr_api_wrapper_input,
    108109                qaddr_tp_over_uds,
    109                 qaddr_uds_appl_qos      // receives messages from an external client via UDS
     110                qaddr_uds_appl_qos,     // receives messages from an external client via UDS
     111                qaddr_mobility
    110112        }; // end qaddr_t
    111113
  • protlib/branches/20090723-multicast/include/network_message.h

    r4107 r4211  
    9999        /// set pointer to beginning
    100100        NetMsg& to_start();
    101         /// copy into NetMsg buffer
     101        /// Copy n bytes from buffer b into NetMsg buffer, starting there at position 0
    102102        uint32 copy_from(const uchar *b, uint32 n);
    103         /// copy into NetMsg buffer
    104         uint32 copy_from(const uchar *b, uint32 start, uint32 end);
     103        /// Copy n bytes from buffer b into NetMsg buffer, starting there at position start
     104        uint32 copy_from(const uchar *b, uint32 start, uint32 n);
    105105        /// copy from NetMsg buffer
    106106        uint32 copy_to(uchar *b, uint32 n) const;
  • protlib/branches/20090723-multicast/include/tp.h

    r3675 r4211  
    8181        /// use_existing_connection indicates whether a new connection will be established
    8282        /// if required (true means that no connection will be set up if none exists yet)
    83         virtual void send(NetMsg* msg, const address& addr, bool use_existing_connection= false) = 0;
     83        virtual void send(NetMsg* msg, const address& addr, bool use_existing_connection= false, const address *local_addr = NULL) = 0;
    8484
    8585        /// terminates an existing signaling association/connection
  • protlib/branches/20090723-multicast/include/tp_over_sctp.h

    r3675 r4211  
    9999{
    100100        // inherited from TP
    101         public:
    102                 virtual void send(NetMsg *msg, const address &addr, bool use_existing_connection);
    103                 virtual void terminate(const address &addr);
     101        public:
     102                virtual void send(NetMsg *msg, const address &addr, bool use_existing_connection, const address *local_addr);
     103                virtual void terminate(const address &addr);
    104104
    105105        // inherited from Thread
  • protlib/branches/20090723-multicast/include/tp_over_tcp.h

    r3675 r4211  
    103103public:
    104104  /// sends a network message, spawns receiver thread if necessary
    105   virtual void send(NetMsg* msg,const address& addr, bool use_existing_connection) { send_cb(msg,addr,use_existing_connection); }
     105  virtual void send(NetMsg* msg, const address& addr, bool use_existing_connection, const address *local_addr) { send_cb(msg,addr,use_existing_connection); }
    106106  virtual void terminate(const address& addr);
    107107 
  • protlib/branches/20090723-multicast/include/tp_over_tls_tcp.h

    r3675 r4211  
    132132public:
    133133  /// sends a network message, spawns receiver thread if necessary
    134   virtual void send(NetMsg* msg,const address& addr, bool use_existing_connection);
     134  virtual void send(NetMsg* msg, const address& addr, bool use_existing_connection, const address *local_addr);
    135135  virtual void terminate(const address& addr);
    136136 
  • protlib/branches/20090723-multicast/include/tp_over_udp.h

    r4198 r4211  
    107107public:
    108108  /// sends a network message, spawns receiver thread if necessary
    109   virtual void send(NetMsg* msg, const address& addr, bool use_existing_connection);
     109  virtual void send(NetMsg* msg, const address& addr, bool use_existing_connection, const address *local_addr= NULL);
    110110  virtual void terminate(const address& addr);
    111111 
     
    149149
    150150  /// send a message to the network via UDP
    151   void udpsend(NetMsg* msg, appladdress* addr);
     151  void udpsend(NetMsg* msg, appladdress* addr, const hostaddress *local_addr);
    152152 
    153153  /// a static starter method to invoke the listener thread
  • protlib/branches/20090723-multicast/include/tp_over_uds.h

    r3675 r4211  
    111111public:
    112112  /// sends a network message, spawns receiver thread if necessary
    113   virtual void send(NetMsg* msg,const address& addr, bool use_existing_connection);
     113  virtual void send(NetMsg* msg, const address& addr, bool use_existing_connection, const address *local_addr);
    114114  virtual void terminate(const address& addr);
    115115 
  • protlib/branches/20090723-multicast/include/tp_queryencap.h

    r4107 r4211  
    126126public:
    127127  virtual void terminate(const address& addr) {};
    128   virtual void send(protlib::NetMsg* msg_to_send, const protlib::address& destaddr, bool use_existing_conn);
     128  virtual void send(protlib::NetMsg* msg_to_send, const protlib::address& destaddr, bool use_existing_conn, const  protlib::address *local_addr);
    129129  /***** inherited from Thread *****/
    130130public:
     
    166166
    167167  /// send a message to the network via UDP
    168   void udpsend(NetMsg* msg, appladdress* addr);
     168  void udpsend(NetMsg* msg, appladdress* addr, const hostaddress *own_addr);
    169169 
    170170  /// a static starter method to invoke the IPv6 interceptor
  • protlib/branches/20090723-multicast/src/Makefile

    r4163 r4211  
    6565#CFLAGS         = -s -finline-functions -O3 -Wuninitialized -Wall $(PROTLIB_CXXFLAGS) # optimization
    6666#CFLAGS         = --pedantic -O -Wno-long-long -Wuninitialized -Wall $(PROTLIB_CXXFLAGS) # optimized
    67 CFLAGS          = --pedantic -Wno-long-long -Wall $(PROTLIB_CXXFLAGS) # development
     67CFLAGS          = --pedantic -Wno-long-long -Wall $(PROTLIB_CXXFLAGS) -Wno-deprecated # development
    6868
    6969CLINK           = -c -o
     
    105105TP_QUERY_ENCAP_OBJ= tp_queryencap.o
    106106
    107 PROTLIB_OBJS    = networkinterface.o address.o ie.o tp.o tp_over_tcp.o tp_over_tls_tcp.o \
     107PROTLIB_OBJS    = networkinterface.o address.o ie.o addresslist.o tp.o tp_over_tcp.o tp_over_tls_tcp.o \
    108108                  cmsghdr_util.o tp_over_udp.o $(TP_QUERY_ENCAP_OBJ) tp_over_uds.o \
    109109                  $(TP_SCTPOBJ) connectionmap.o connectionmap_uds.o queuemanager.o fqueue.o \
    110110                  timer.o timer_module.o logfile.o fqueue.o protlib_types.o threads.o \
    111111                  threadsafe_db.o setuid.o messages.o network_message.o \
    112                   configuration.o configpar.o configpar_repository.o configfile.o
     112                  configuration.o configpar.o configpar_repository.o configfile.o \
     113                  routing_util.o readnl.o
    113114
    114115ALLSOURCES        := $(wildcard *.cpp)
     
    145146tests: libs test_log test_timer test_threads \
    146147        test_fqueue test_timer_module test_tp_over_tcp\
    147          test_setuid test_radix_trie test_addrlist
     148         test_setuid test_radix_trie test_addrlist \
     149         test_tp_queryencap
    148150
    149151test_log: test_log.o logfile.o
     
    171173test_tp_over_udp: test_tp_over_udp.o $(PROTLIB) $(FQUEUE_LIB)
    172174        $(CPP) $(CFLAGS) -o $@ $^ $(SHLIBS) $(FQUEUE_LIB)
     175
     176test_tp_queryencap: test_tp_queryencap.o $(PROTLIB) $(FQUEUE_LIB)
     177        $(CPP) $(CFLAGS) -o $@ $^ $(SHLIBS) -lipq $(FQUEUE_LIB)
    173178
    174179test_tp_over_sctp: test_tp_over_sctp.o tp.o tp_over_sctp.o queuemanager.o\
  • protlib/branches/20090723-multicast/src/address.cpp

    r4107 r4211  
    3737#include "threadsafe_db.h"
    3838#include "logfile.h"
     39#include "rfc5014_hack.h"
    3940
    4041#include <net/if.h>
     
    4445#include <iomanip>
    4546#include <netdb.h>
     47#include <err.h>
    4648
    4749namespace protlib {
     
    787789                // difference past na->prefix_length
    788790                *pos = diff;
     791                if ((w1 == w2) && (prefix_length > na->prefix_length)) {
     792                    return 1;
     793                }
     794         
    789795                return (((w1 & (1 << (32 - diff))) >>
    790796                    (32 - diff)) == 0 ? -1 : 1);
     
    859865} // end operator==
    860866
    861 AddressList::AddrProperty *AddressList::LocalAddr_P;
    862 AddressList::AddrProperty *AddressList::ConfiguredAddr_P;
    863 AddressList::AddrProperty *AddressList::IgnoreAddr_P;
    864 AddressList::AddrProperty *AddressList::AnyAddr_P;
    865 
    866 AddressList::AddressList()
    867 {
    868         if (LocalAddr_P == 0) {
    869                 LocalAddr_P = new AddrProperty("local");
    870                 ConfiguredAddr_P = new AddrProperty("configured");
    871                 IgnoreAddr_P = new AddrProperty("ignore");
    872                 AnyAddr_P = new AddrProperty("wildcard");
    873         }
    874         interfaces = 0;
    875 }
    876 
    877 AddressList::~AddressList()
    878 {
    879         // Refcount AddressLists in order to GC properties?
    880 }
    881 
    882 AddressList::iflist_t *
    883 AddressList::get_interfaces()
    884 {
    885         iflist_t *iflist;
    886 
    887         if (interfaces != 0)
    888                 iflist = new iflist_t(*interfaces);
    889         else {
    890                 iflist = new iflist_t();
    891                 getifaddrs_iflist(*iflist);
    892         }
    893 
    894         return iflist;
    895 }
    896 
    897 bool
    898 AddressList::by_interface(bool start_empty)
    899 {
    900         if (interfaces != 0)
    901                 return false;
    902 
    903         interfaces = new iflist_t();
    904         if (!start_empty)
    905                 getifaddrs_iflist(*interfaces);
    906 
    907         return true;
    908 }
    909 
    910 bool
    911 AddressList::add_interface(char *name)
    912 {
    913         if (interfaces == 0)
    914                 return false;
    915 
    916         return (interfaces->insert(name)).second;
    917 }
    918 
    919 bool
    920 AddressList::del_interface(char *name)
    921 {
    922         if (interfaces == 0)
    923                 return false;
    924 
    925         return (interfaces->erase(name) > 0);
    926 }
    927 
    928 bool
    929 AddressList::add_property(netaddress &na, AddrProperty *p, bool propagate)
    930 {
    931         propmap_t *props, *lpfm_props;
    932         propmap_t::iterator it;
    933         addr2prop_t::node *node;
    934 
    935         node = prop_trie.lookup_node(na, false, false);
    936         if (node != NULL) {
    937                 props = node->data;
    938                 if (props == NULL) {
    939                         props = new propmap_t();
    940                         node->data = props;
    941                 }
    942                 props->insert(pair<AddrProperty *, bool>(p, propagate));
    943                
    944         } else {
    945                 props = new propmap_t();
    946                 props->insert(pair<AddrProperty *, bool>(p, propagate));
    947                 node = prop_trie.insert(na, *props);
    948         }
    949 
    950         if (propagate)
    951                 bequeath(node, p, true);
    952 
    953         // copy lpfm properties
    954         lpfm_props = prop_trie.lookup(na, true);
    955         if (lpfm_props == NULL)
    956                 return true;
    957 
    958         for (it = lpfm_props->begin(); it != lpfm_props->end(); it++) {
    959                 if ((*it).second)
    960                         props->insert((*it));
    961         }
    962 
    963         return true;
    964 }
    965 
    966 bool
    967 AddressList::del_property(netaddress &na, AddrProperty *p, bool propagate)
    968 {
    969         propmap_t *props, *lpfm_props;
    970         propmap_t::iterator it;
    971         addr2prop_t::node *node;
    972 
    973         node = prop_trie.lookup_node(na, false, true);
    974         if (node == NULL) {
    975                 // no exact match
    976                 if (!propagate) {
    977                         node = prop_trie.lookup_node(na, true, true);
    978                         if (node == NULL) {
    979                                 // no lpfm either, we're done
    980                                 return false;
    981                         }
    982 
    983                         props = node->data;
    984                         it = props->find(p);
    985                         if (it == props->end()) {
    986                                 // lpfm doesn't have p set -> done
    987                                 return false;
    988                         }
    989                 }
    990                 // insert an empty propmap
    991                 props = new propmap_t();
    992                 node = prop_trie.insert(na, *props);
    993 
    994                 // copy other lpfm properties
    995                 lpfm_props = prop_trie.lookup(na, true);
    996                 if (p != AnyAddr_P && lpfm_props != NULL) {
    997                         for (it = lpfm_props->begin(); it != lpfm_props->end();
    998                             it++) {
    999                                 if ((*it).first != p && (*it).second)
    1000                                         props->insert((*it));
    1001                         }
    1002                 }
    1003         } else {
    1004                 props = node->data;
    1005                 if (p == AnyAddr_P) {
    1006                         props->clear();
    1007                 } else {
    1008                         it = props->find(p);
    1009                         if (it == props->end() && !propagate)
    1010                                 return false;
    1011 
    1012                         props->erase(it);
    1013                 }
    1014         }
    1015 
    1016         if (propagate)
    1017                 bequeath(node, p, false);
    1018 
    1019         return true;
    1020 }
    1021 
    1022 bool
    1023 AddressList::add_host_prop(const char *name, AddrProperty *p)
    1024 {
    1025         netaddress na;
    1026         sockaddr_in *sin;
    1027         sockaddr_in6 *sin6;
    1028         struct addrinfo hints = {0}, *res, *cur;
    1029         int error;
    1030         char buf[1024];
    1031 
    1032         if (name == NULL) {
    1033                 name = buf;
    1034                 if (gethostname(buf, sizeof(buf)) != 0)
    1035                         return false;
    1036                 buf[sizeof(buf) - 1] = '\0';
    1037         }
    1038         hints.ai_flags = AI_ADDRCONFIG | AI_CANONNAME;
    1039         hints.ai_family = AF_UNSPEC;
    1040         error = getaddrinfo(name, NULL, &hints, &res);
    1041         if (error != 0)
    1042                 return false;
    1043 
    1044         for(cur = res; cur != NULL && error == 0; cur = cur->ai_next) {
    1045                 if (cur->ai_family == AF_INET) {
    1046                         sin = (struct sockaddr_in *)cur->ai_addr;
    1047                         na.set_ip(sin->sin_addr);
    1048                         na.set_pref_len(32);
    1049                 } else if (cur->ai_family == AF_INET6) {
    1050                         sin6 = (struct sockaddr_in6 *)cur->ai_addr;
    1051                         na.set_ip(sin6->sin6_addr);
    1052                         na.set_pref_len(128);
    1053                 } else
    1054                         continue;
    1055 
    1056                 // cout << ++i << "XXMOB: " << na << endl;
    1057 
    1058                 error += add_property(na, p) ? 0 : 1;
    1059                 // XXXMOB: for some reason we need a 'reset' here
    1060                 //         if we want to use /etc/hosts
    1061                 na.set_ip("127.0.0.1");
    1062         }
    1063         freeaddrinfo(res);
    1064 
    1065         return (error == 0);
    1066 }
    1067 
    1068 bool
    1069 AddressList::del_host_prop(const char *name, AddrProperty *p)
    1070 {
    1071         netaddress na;
    1072         sockaddr_in *sin;
    1073         sockaddr_in6 *sin6;
    1074         struct addrinfo hints = {0}, *res, *cur;
    1075         int error;
    1076         char buf[1024];
    1077 
    1078         if (name == NULL) {
    1079                 name = buf;
    1080                 if (gethostname(buf, sizeof(buf)) != 0)
    1081                         return false;
    1082                 buf[sizeof(buf) - 1] = '\0';
    1083         }
    1084         hints.ai_flags = AI_ADDRCONFIG;
    1085         hints.ai_family = AF_UNSPEC;
    1086         error = getaddrinfo(name, NULL, &hints, &res);
    1087         if (error != 0)
    1088                 return false;
    1089 
    1090         for(cur = res; cur != NULL && error == 0; cur = cur->ai_next) {
    1091                 if (cur->ai_family == AF_INET) {
    1092                         sin = (struct sockaddr_in *)cur->ai_addr;
    1093                         na.set_ip(sin->sin_addr);
    1094                         na.set_pref_len(32);
    1095                 } else if (cur->ai_family == AF_INET6) {
    1096                         sin6 = (struct sockaddr_in6 *)cur->ai_addr;
    1097                         na.set_ip(sin6->sin6_addr);
    1098                         na.set_pref_len(128);
    1099                 } else
    1100                         continue;
    1101 
    1102                 error += del_property(na, p) ? 0 : 1;
    1103         }
    1104         freeaddrinfo(res);
    1105 
    1106         return (error == 0);
    1107 }
    1108 
    1109 bool
    1110 AddressList::ignore(netaddress &na, bool propagate)
    1111 {
    1112         del_property(na, AnyAddr_P, propagate);
    1113         return add_property(na, IgnoreAddr_P);
    1114 }
    1115 
    1116 bool
    1117 AddressList::unignore(netaddress &na, bool propagate)
    1118 {
    1119         return del_property(na, IgnoreAddr_P, propagate);
    1120 }
    1121 
    1122 bool
    1123 AddressList::ignore_bogons(void)
    1124 {
    1125         netaddress na;
    1126 
    1127         // according to http://www.cymru.com/Documents/bogon-list.html
    1128         // 4.8 (30 Apr 2009)
    1129         na.set_ip("0.0.0.0");na.set_pref_len(7);
    1130         ignore(na);
    1131         na.set_ip("2.0.0.0");na.set_pref_len(8);
    1132         ignore(na);
    1133         na.set_ip("5.0.0.0");na.set_pref_len(8);
    1134         ignore(na);
    1135         na.set_ip("10.0.0.0");na.set_pref_len(8);
    1136         ignore(na);
    1137         na.set_ip("14.0.0.0");na.set_pref_len(8);
    1138         ignore(na);
    1139         na.set_ip("23.0.0.0");na.set_pref_len(8);
    1140         ignore(na);
    1141         na.set_ip("27.0.0.0");na.set_pref_len(8);
    1142         ignore(na);
    1143         na.set_ip("31.0.0.0");na.set_pref_len(8);
    1144         ignore(na);
    1145         na.set_ip("36.0.0.0");na.set_pref_len(7);
    1146         ignore(na);
    1147         na.set_ip("39.0.0.0");na.set_pref_len(8);
    1148         ignore(na);
    1149         na.set_ip("42.0.0.0");na.set_pref_len(8);
    1150         ignore(na);
    1151         na.set_ip("46.0.0.0");na.set_pref_len(8);
    1152         ignore(na);
    1153         na.set_ip("49.0.0.0");na.set_pref_len(8);
    1154         ignore(na);
    1155         na.set_ip("50.0.0.0");na.set_pref_len(8);
    1156         ignore(na);
    1157         na.set_ip("100.0.0.0");na.set_pref_len(6);
    1158         ignore(na);
    1159         na.set_ip("104.0.0.0");na.set_pref_len(5);
    1160         ignore(na);
    1161         na.set_ip("169.254.0.0");na.set_pref_len(16);
    1162         ignore(na);
    1163         na.set_ip("175.0.0.0");na.set_pref_len(7);
    1164         ignore(na);
    1165         na.set_ip("176.0.0.0");na.set_pref_len(5);
    1166         ignore(na);
    1167         na.set_ip("179.0.0.0");na.set_pref_len(5);
    1168         ignore(na);
    1169         na.set_ip("181.0.0.0");na.set_pref_len(6);
    1170         ignore(na);
    1171         na.set_ip("182.0.0.0");na.set_pref_len(6);
    1172         ignore(na);
    1173         na.set_ip("185.0.0.0");na.set_pref_len(6);
    1174         ignore(na);
    1175         na.set_ip("191.0.0.0");na.set_pref_len(8);
    1176         ignore(na);
    1177         na.set_ip("192.0.2.0");na.set_pref_len(24);
    1178         ignore(na);
    1179         na.set_ip("197.0.0.0");na.set_pref_len(8);
    1180         ignore(na);
    1181         na.set_ip("198.18.0.0");na.set_pref_len(15);
    1182         ignore(na);
    1183         na.set_ip("223.0.0.0");na.set_pref_len(8);
    1184         ignore(na);
    1185         na.set_ip("240.0.0.0");na.set_pref_len(4);
    1186         ignore(na);
    1187         // according to http://www.cymru.com/Bogons/v6bogon.html (2008-05-20)
    1188         na.set_ip("2001:db8::");na.set_pref_len(32);
    1189         ignore(na);
    1190         na.set_ip("0000::");na.set_pref_len(3);
    1191         ignore(na);
    1192         na.set_ip("2000::");na.set_pref_len(16);
    1193         ignore(na);
    1194         na.set_ip("2001:1::");na.set_pref_len(32);
    1195         ignore(na);
    1196         na.set_ip("2001:2::");na.set_pref_len(31);
    1197         ignore(na);
    1198         na.set_ip("2001:4::");na.set_pref_len(30);
    1199         ignore(na);
    1200         na.set_ip("2001:8::");na.set_pref_len(29);
    1201         ignore(na);
    1202         na.set_ip("2001:10::");na.set_pref_len(28);
    1203         ignore(na);
    1204         na.set_ip("2001:20::");na.set_pref_len(27);
    1205         ignore(na);
    1206         na.set_ip("2001:40::");na.set_pref_len(26);
    1207         ignore(na);
    1208         na.set_ip("2001:80::");na.set_pref_len(25);
    1209         ignore(na);
    1210         na.set_ip("2001:100::");na.set_pref_len(24);
    1211         ignore(na);
    1212         na.set_ip("2001:1000::");na.set_pref_len(23);
    1213         ignore(na);
    1214         na.set_ip("2001:4e00::");na.set_pref_len(23);
    1215         ignore(na);
    1216         na.set_ip("2001:6000::");na.set_pref_len(19);
    1217         ignore(na);
    1218         na.set_ip("2001:c000::");na.set_pref_len(18);
    1219         ignore(na);
    1220         na.set_ip("2003:4000::");na.set_pref_len(18);
    1221         ignore(na);
    1222         na.set_ip("2003:8000::");na.set_pref_len(17);
    1223         ignore(na);
    1224         na.set_ip("2004::");na.set_pref_len(14);
    1225         ignore(na);
    1226         na.set_ip("2008::");na.set_pref_len(13);
    1227         ignore(na);
    1228         na.set_ip("2010::");na.set_pref_len(12);
    1229         ignore(na);
    1230         na.set_ip("2020::");na.set_pref_len(11);
    1231         ignore(na);
    1232         na.set_ip("2040::");na.set_pref_len(10);
    1233         ignore(na);
    1234         na.set_ip("2080::");na.set_pref_len(9);
    1235         ignore(na);
    1236         na.set_ip("2100::");na.set_pref_len(8);
    1237         ignore(na);
    1238         na.set_ip("2200::");na.set_pref_len(7);
    1239         ignore(na);
    1240         na.set_ip("2410::");na.set_pref_len(12);
    1241         ignore(na);
    1242         na.set_ip("2420::");na.set_pref_len(11);
    1243         ignore(na);
    1244         na.set_ip("2440::");na.set_pref_len(10);
    1245         ignore(na);
    1246         na.set_ip("2480::");na.set_pref_len(9);
    1247         ignore(na);
    1248         na.set_ip("2500::");na.set_pref_len(8);
    1249         ignore(na);
    1250         na.set_ip("2610:200::");na.set_pref_len(23);
    1251         ignore(na);
    1252         na.set_ip("2610:400::");na.set_pref_len(22);
    1253         ignore(na);
    1254         na.set_ip("2610:800::");na.set_pref_len(21);
    1255         ignore(na);
    1256         na.set_ip("2610:1000::");na.set_pref_len(20);
    1257         ignore(na);
    1258         na.set_ip("2610:2000::");na.set_pref_len(19);
    1259         ignore(na);
    1260         na.set_ip("2610:4000::");na.set_pref_len(18);
    1261         ignore(na);
    1262         na.set_ip("2610:8000::");na.set_pref_len(17);
    1263         ignore(na);
    1264         na.set_ip("2611::");na.set_pref_len(16);
    1265         ignore(na);
    1266         na.set_ip("2612::");na.set_pref_len(15);
    1267         ignore(na);
    1268         na.set_ip("2614::");na.set_pref_len(14);
    1269         ignore(na);
    1270         na.set_ip("2618::");na.set_pref_len(13);
    1271         ignore(na);
    1272         na.set_ip("2620:200::");na.set_pref_len(23);
    1273         ignore(na);
    1274         na.set_ip("2620:400::");na.set_pref_len(22);
    1275         ignore(na);
    1276         na.set_ip("2620:800::");na.set_pref_len(21);
    1277         ignore(na);
    1278         na.set_ip("2620:1000::");na.set_pref_len(20);
    1279         ignore(na);
    1280         na.set_ip("2620:2000::");na.set_pref_len(19);
    1281         ignore(na);
    1282         na.set_ip("2620:4000::");na.set_pref_len(18);
    1283         ignore(na);
    1284         na.set_ip("2620:8000::");na.set_pref_len(17);
    1285         ignore(na);
    1286         na.set_ip("2621::");na.set_pref_len(16);
    1287         ignore(na);
    1288         na.set_ip("2622::");na.set_pref_len(15);
    1289         ignore(na);
    1290         na.set_ip("2624::");na.set_pref_len(14);
    1291         ignore(na);
    1292         na.set_ip("2628::");na.set_pref_len(13);
    1293         ignore(na);
    1294         na.set_ip("2630::");na.set_pref_len(12);
    1295         ignore(na);
    1296         na.set_ip("2640::");na.set_pref_len(10);
    1297         ignore(na);
    1298         na.set_ip("2680::");na.set_pref_len(9);
    1299         ignore(na);
    1300         na.set_ip("2700::");na.set_pref_len(8);
    1301         ignore(na);
    1302         na.set_ip("2810::");na.set_pref_len(12);
    1303         ignore(na);
    1304         na.set_ip("2820::");na.set_pref_len(11);
    1305         ignore(na);
    1306         na.set_ip("2840::");na.set_pref_len(10);
    1307         ignore(na);
    1308         na.set_ip("2880::");na.set_pref_len(9);
    1309         ignore(na);
    1310         na.set_ip("2900::");na.set_pref_len(8);
    1311         ignore(na);
    1312         na.set_ip("2a10::");na.set_pref_len(8);
    1313         ignore(na);
    1314         na.set_ip("2a20::");na.set_pref_len(8);
    1315         ignore(na);
    1316         na.set_ip("2a40::");na.set_pref_len(8);
    1317         ignore(na);
    1318         na.set_ip("2a80::");na.set_pref_len(8);
    1319         ignore(na);
    1320         na.set_ip("2b00::");na.set_pref_len(8);
    1321         ignore(na);
    1322         na.set_ip("2c10::");na.set_pref_len(12);
    1323         ignore(na);
    1324         na.set_ip("2c20::");na.set_pref_len(11);
    1325         ignore(na);
    1326         na.set_ip("2c40::");na.set_pref_len(10);
    1327         ignore(na);
    1328         na.set_ip("2c80::");na.set_pref_len(9);
    1329         ignore(na);
    1330         na.set_ip("2d00::");na.set_pref_len(8);
    1331         ignore(na);
    1332         na.set_ip("2e00::");na.set_pref_len(7);
    1333         ignore(na);
    1334         na.set_ip("3000::");na.set_pref_len(4);
    1335         ignore(na);
    1336         na.set_ip("4000::");na.set_pref_len(2);
    1337         ignore(na);
    1338         na.set_ip("8000::");na.set_pref_len(1);
    1339         ignore(na);
    1340         na.set_ip("F000::");na.set_pref_len(5);
    1341         ignore(na);
    1342         na.set_ip("F800::");na.set_pref_len(6);
    1343         ignore(na);
    1344         na.set_ip("FC00::");na.set_pref_len(7);
    1345         ignore(na);
    1346         na.set_ip("FE00::");na.set_pref_len(9);
    1347         ignore(na);
    1348 
    1349         return true;
    1350 }
    1351 
    1352 bool
    1353 AddressList::ignore_locals(void)
    1354 {
    1355         netaddress na;
    1356 
    1357         na.set_ip("10.0.0.0");na.set_pref_len(8);
    1358         ignore(na);
    1359         na.set_ip("172.16.0.0");na.set_pref_len(12);
    1360         ignore(na);
    1361         na.set_ip("192.168.0.0");na.set_pref_len(16);
    1362         ignore(na);
    1363         na.set_ip("FE80::");na.set_pref_len(10);
    1364         ignore(na);
    1365         na.set_ip("FEC0::");na.set_pref_len(10);
    1366         ignore(na);
    1367 
    1368         return true;
    1369 }
    1370 
    1371 bool
    1372 AddressList::ignore_loopback(void)
    1373 {
    1374         netaddress na;
    1375 
    1376         na.set_ip("127.0.0.0");na.set_pref_len(8);
    1377         ignore(na);
    1378         na.set_ip("::1");na.set_pref_len(128);
    1379         ignore(na);
    1380 
    1381         return true;
    1382 }
    1383 
    1384 bool
    1385 AddressList::addr_is(netaddress &na, AddrProperty *prop)
    1386 {
    1387         propmap_t *props;
    1388         propmap_t::iterator it;
    1389 
    1390         if (addr_is_in(na, IgnoreAddr_P))
    1391                 return false;
    1392 
    1393         props = prop_trie.lookup(na, false);
    1394         if (props != NULL) {
    1395                 it = props->find(prop);
    1396                 if (it != props->end()) {
    1397                         return true;
    1398                 }
    1399         }
    1400 
    1401         if (prop != LocalAddr_P)
    1402                 return false;
    1403 
    1404         return getifaddrs_is_local(na);
    1405 }
    1406 
    1407 bool
    1408 AddressList::addr_is_in(netaddress &na, AddrProperty *prop)
    1409 {
    1410         addr2prop_t::node *node;
    1411         propmap_t *props;
    1412         propmap_t::iterator it;
    1413 
    1414         node = prop_trie.lookup_node(na, true, true);
    1415         if (node == NULL)
    1416                 return false;
    1417 
    1418         props = node->data;
    1419         it = props->find(prop);
    1420         if (it == props->end())
    1421                 return false;
    1422 
    1423         if (!(*it).second && props != prop_trie.lookup(na, false))
    1424                         return false;
    1425 
    1426         return true;
    1427 }
    1428 
    1429 AddressList::addrlist_t *
    1430 AddressList::get_addrs(AddrProperty *prop)
    1431 {
    1432         addr2prop_t::node *node;
    1433         netaddress na;
    1434         addrlist_t *res = new addrlist_t();
    1435 
    1436         if (res == 0)
    1437                 return res;
    1438 
    1439         if (prop == LocalAddr_P || prop == AnyAddr_P)
    1440                 getifaddrs_get_addrs(*res);
    1441 
    1442         na.set_ip("0.0.0.0");
    1443         na.set_pref_len(0);
    1444         node = prop_trie.lookup_node(na, true, false);
    1445         collect(node, prop, *res);
    1446 
    1447         na.set_ip("::");
    1448         node = prop_trie.lookup_node(na, true, false);
    1449         collect(node, prop, *res);
    1450 
    1451         return res;
    1452 }
    1453 
    1454 netaddress *
    1455 AddressList::get_first(AddrProperty *p, bool IPv4)
    1456 {
    1457         addr2prop_t::node *node;
    1458         netaddress na;
    1459         addrlist_t list;
    1460         addrlist_t::iterator it;
    1461 
    1462         if (IPv4) {
    1463                 na.set_ip("0.0.0.0");
    1464                 na.set_pref_len(0);
    1465         } else {
    1466                 na.set_ip("::");
    1467                 na.set_pref_len(0);
    1468         }
    1469 
    1470         node = prop_trie.lookup_node(na, true, false);
    1471         node = collect_first(node, p);
    1472         if (node != NULL)
    1473                 return new netaddress(*node->key);
    1474 
    1475         if (p == LocalAddr_P) {
    1476                 getifaddrs_get_addrs(list);
    1477                 for (it = list.begin(); it != list.end(); it++)
    1478                         if ((*it).is_ipv4() == IPv4)
    1479                                 return new netaddress(*it);
    1480         }
    1481 
    1482         return NULL;
    1483 }
    1484 
    1485 netaddress *
    1486 AddressList::get_src_addr(const netaddress &dest, uint32_t *prefs)
    1487 {
    1488         netaddress *res;
    1489         int sfd;
    1490 
    1491         sfd = socket(dest.is_ipv4()?AF_INET:AF_INET6, SOCK_DGRAM, 0);
    1492         if (sfd == -1)
    1493                 return NULL;
    1494 
    1495 #ifdef IPV6_ADDR_PREFERENCES
    1496         if (prefs != NULL && setsockopt(s, IPV6_ADDR_PREFERENCES,
    1497             (void *)prefs, sizeof (*prefs)) == -1) {
    1498                 close(sfd);
    1499                 return NULL;
    1500         }
    1501 #endif
    1502         if (dest.is_ipv4()) {
    1503                 struct sockaddr_in sin = {0};
    1504                 socklen_t slen = sizeof(sin);
    1505                 sin.sin_family = AF_INET;
    1506                 sin.sin_port = htons(4);
    1507                 dest.get_ip(sin.sin_addr);
    1508                 if (connect(sfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
    1509                         close(sfd);
    1510                         return NULL;
    1511                 }
    1512                 if (getsockname(sfd, (struct sockaddr *)&sin, &slen) == -1) {
    1513                         close(sfd);
    1514                         return NULL;
    1515                 }
    1516                 close(sfd);
    1517                 res = new netaddress();
    1518                 res->set_ip(sin.sin_addr);
    1519                 res->set_pref_len(32);
    1520                 return (res);
    1521         } else {
    1522                 struct sockaddr_in6 sin6 = {0};
    1523                 socklen_t slen = sizeof(sin6);
    1524                 sin6.sin6_family = AF_INET6;
    1525                 sin6.sin6_port = htons(4);
    1526                 dest.get_ip(sin6.sin6_addr);
    1527                 if (connect(sfd, (struct sockaddr *)&sin6,
    1528                     sizeof(sin6)) == -1) {
    1529                         close(sfd);
    1530                         return NULL;
    1531                 }
    1532                 if (getsockname(sfd, (struct sockaddr *)&sin6, &slen) == -1) {
    1533                         close(sfd);
    1534                         return NULL;
    1535                 }
    1536                 close(sfd);
    1537                 res = new netaddress();
    1538                 res->set_ip(sin6.sin6_addr);
    1539                 res->set_pref_len(128);
    1540                 return (res);
    1541         }
    1542 }
    1543 
    1544 void
    1545 AddressList::getifaddrs_iflist(iflist_t &list)
    1546 {
    1547         struct ifaddrs *ifap, *cifa;
    1548 
    1549         if (::getifaddrs(&ifap) != 0)
    1550                 return;
    1551 
    1552         for (cifa = ifap; cifa != NULL; cifa = cifa->ifa_next) {
    1553                 list.insert(cifa->ifa_name);
    1554         }
    1555 
    1556         freeifaddrs(ifap);
    1557 }
    1558 
    1559 bool
    1560 AddressList::getifaddrs_is_local(netaddress &na)
    1561 {
    1562         struct ifaddrs *ifap, *cifa;
    1563 
    1564         if (::getifaddrs(&ifap) != 0)
    1565                 return false;
    1566 
    1567         for (cifa = ifap; cifa != NULL; cifa = cifa->ifa_next) {
    1568                 hostaddress ha;
    1569 
    1570                 if (cifa->ifa_addr->sa_family == AF_INET) {
    1571                         ha.set_ip(
    1572                             ((struct sockaddr_in *)cifa->ifa_addr)->sin_addr);
    1573                 } else if (cifa->ifa_addr->sa_family == AF_INET6) {
    1574                         ha.set_ip(
    1575                             ((struct sockaddr_in6 *)cifa->ifa_addr)->sin6_addr);
    1576                 } else {
    1577                         continue;
    1578                 }
    1579 
    1580                 if (interfaces &&
    1581                     interfaces->find(cifa->ifa_name) == interfaces->end())
    1582                         continue;
    1583 
    1584                 if (ha.match_against(na) >= na.get_pref_len()) {
    1585                         freeifaddrs(ifap);
    1586                         return true;
    1587                 }
    1588         }
    1589 
    1590         freeifaddrs(ifap);
    1591 
    1592         return false;
    1593 }
    1594 
    1595 void
    1596 AddressList::getifaddrs_get_addrs(addrlist_t &list)
    1597 {
    1598         struct ifaddrs *ifap, *cifa;
    1599 
    1600         if (::getifaddrs(&ifap) != 0)
    1601                 return;
    1602 
    1603         for (cifa = ifap; cifa != NULL; cifa = cifa->ifa_next) {
    1604                 hostaddress *ha;
    1605                 netaddress na;
    1606 
    1607                 if (interfaces &&
    1608                     interfaces->find(cifa->ifa_name) == interfaces->end())
    1609                         continue;
    1610 
    1611                 if (cifa->ifa_addr->sa_family == AF_INET) {
    1612                         ha = new hostaddress;
    1613                         ha->set_ip(
    1614                             ((struct sockaddr_in *)cifa->ifa_addr)->sin_addr);
    1615                         na.set_pref_len(32);
    1616                 } else if (cifa->ifa_addr->sa_family == AF_INET6) {
    1617                         ha = new hostaddress;
    1618                         ha->set_ip(
    1619                             ((struct sockaddr_in6 *)cifa->ifa_addr)->sin6_addr);
    1620                         na.set_pref_len(128);
    1621                 } else {
    1622                         continue;
    1623                 }
    1624 
    1625                 na.set_ip(*ha);
    1626                 if (!addr_is_in(na, IgnoreAddr_P))
    1627                         list.insert(*ha);
    1628         }
    1629 
    1630         freeifaddrs(ifap);
    1631 }
    1632 
    1633 void
    1634 AddressList::bequeath(addr2prop_t::node *head, AddrProperty *p, bool add)
    1635 {
    1636         propmap_t *props;
    1637         propmap_t::iterator it;
    1638 
    1639         if (p == AnyAddr_P && add)
    1640                 return;
    1641 
    1642         props = head->data;
    1643         if (props != NULL) {
    1644                 if (p == AnyAddr_P) {
    1645                         props->clear();
    1646                 } else {
    1647                         if (add) {
    1648                                 props->insert(pair<AddrProperty *, bool>
    1649                                     (p, true));
    1650                         } else {
    1651                                 it = props->find(p);
    1652                                 if (it != props->end())
    1653                                         props->erase(it);
    1654                         }
    1655                 }
    1656         }
    1657 
    1658         if (head->left->index > head->index)
    1659                 bequeath(head->left, p, add);
    1660         if (head->right->index > head->index)
    1661                 bequeath(head->right, p, add);
    1662 }
    1663 
    1664 void
    1665 AddressList::collect(addr2prop_t::node *head, AddrProperty *p,
    1666     addrlist_t &list)
    1667 {
    1668         propmap_t *props;
    1669         propmap_t::iterator it;
    1670 
    1671         props = head->data;
    1672         if (props != NULL) {
    1673                 if (p == AnyAddr_P) {
    1674                         it = props->begin();
    1675                 } else {
    1676                         it = props->find(p);
    1677                 }
    1678                 if (it != props->end()) {
    1679                         list.insert(*(new netaddress(*head->key)));
    1680                 }
    1681         }
    1682 
    1683         if (head->left->index > head->index)
    1684                 collect(head->left, p, list);
    1685         if (head->right->index > head->index)
    1686                 collect(head->right, p, list);
    1687        
    1688 }
    1689 
    1690 AddressList::addr2prop_t::node *
    1691 AddressList::collect_first(addr2prop_t::node *head, AddrProperty *p)
    1692 {
    1693         addr2prop_t::node *res = NULL;
    1694         propmap_t *props;
    1695         propmap_t::iterator it;
    1696 
    1697         props = head->data;
    1698         if (props != NULL) {
    1699                 if (p == AnyAddr_P) {
    1700                         it = props->begin();
    1701                 } else {
    1702                         it = props->find(p);
    1703                 }
    1704                 if (it != props->end()) {
    1705                         return head;
    1706                 }
    1707         }
    1708 
    1709         if (head->left->index > head->index) {
    1710                 res = collect_first(head->left, p);
    1711                 if (res != NULL)
    1712                         return res;
    1713         }
    1714         if (head->right->index > head->index) {
    1715                 res = collect_first(head->right, p);
    1716                 if (res != NULL)
    1717                         return res;
    1718         }
    1719 
    1720         return NULL;
    1721 }
    1722867
    1723868
  • protlib/branches/20090723-multicast/src/cmsghdr_util.cpp

    • Property svn:keywords set to Id HeadURL Rev
    r4107 r4211  
    198198}
    199199
    200 /** Adds the outgoing interface index to a msghdr
    201  *
    202  * This function adds a pkt_info for setting the outgoing interface to the
     200/** Adds the outgoing interface index or outgoing address to a msghdr
     201 *
     202 * This function adds a pkt_info for setting the outgoing interface/address to the
    203203 * msg_control member of the given msghdr.  For this purpose it writes a
    204204 * cmsghdr struct to pointer cmsg, which MUST point to the memory area
     
    211211 * @param cmsg  the location where the cmsghdr structure for the hop limit
    212212 *              should be written to
    213  * @oif         the desired outgoing interface index
     213 * @param oif   the desired outgoing interface index, may be 0 if unset (usually if outgoing_address is given)
     214 * @param outgoing_address  the ip source address, may be NULL if unset (usually if oif is given)
    214215 * @return      zero on success, -1 on error
    215216 */
    216217int
    217 cmsghdr_build_oif(msghdr *msg, cmsghdr *cmsg, uint16_t oif)
     218cmsghdr_build_oif(msghdr *msg, cmsghdr *cmsg, const hostaddress* outgoing_address, uint16_t oif)
    218219{
    219220    assert(msg);
    220221    assert(cmsg != NULL);
    221     assert(oif > 0);
    222222
    223223    in6_pktinfo pktinfo;
     
    226226      return -1;
    227227
    228     pktinfo.ipi6_addr = in6addr_any;
     228    if (outgoing_address)
     229            outgoing_address->get_ip(pktinfo.ipi6_addr);
     230    else
     231            pktinfo.ipi6_addr = in6addr_any;
     232
    229233    pktinfo.ipi6_ifindex = oif;
    230234
     
    236240}
    237241
     242
     243
    238244/** Set ancillary data to configure Routing Alert Option, outgoing interface and IP hop limit
    239245 *
     
    256262 *              be set for
    257263 * @param rao   The desired Router Alert Option value (or -1 if none wanted)
     264 * @param outgoing_address The desired outgoing address
     265 *              (or NULL if the kernel should choose the outgoing address)
    258266 * @param oif   The desired outgoing interface index (> 0)
    259267 *              (or zero if the kernel should choose the outgoing interface)
     
    262270 */
    263271void
    264 set_ancillary_data(struct msghdr *msg, int rao, uint16_t oif, int hlim)
     272set_ancillary_data(struct msghdr *msg, int rao, const hostaddress* outgoing_address, uint16_t oif, int hlim)
    265273{
    266274  const char *const methodname= "protlib::util::set_ancillary_data()";
     
    288296    buflength += CMSG_SPACE(sizeof(int));
    289297  }
    290   if (oif > 0) {
     298  if (oif > 0 || outgoing_address != NULL) {
    291299    in6_pktinfo pktinfo;
    292300    buflength += CMSG_SPACE(sizeof(pktinfo));
     
    332340    cmsgptr = CMSG_NXTHDR(msg, cmsgptr);
    333341  }
    334   if (oif > 0)
     342  if (oif > 0 || outgoing_address != NULL)
    335343  {
    336     DLog(methodname, "Adding IP outgoing interface " << oif);
    337     int rv = cmsghdr_build_oif(msg, cmsgptr, oif);
     344    if (oif > 0)
     345            DLog(methodname, "Adding IP outgoing interface " << oif);
     346    if (outgoing_address != NULL)
     347            DLog(methodname, "Adding outgoing IP address " << *outgoing_address);
     348
     349    int rv = cmsghdr_build_oif(msg, cmsgptr, outgoing_address, oif);
    338350    if (rv != 0) {
    339351    }
    340352    cmsgptr = CMSG_NXTHDR(msg, cmsgptr);
    341353  }
     354
    342355#ifdef DEBUG_HARD
    343356  dump_cmsghdr(msg); // for debugging purposes (declaration see below)
  • protlib/branches/20090723-multicast/src/cmsghdr_util.h

    • Property svn:keywords set to Id HeadURL Rev
    r4107 r4211  
    3333
    3434#include <sys/socket.h> /* msghdr */
     35#include <address.h>
    3536
    3637namespace protlib {
     
    7980
    8081// Builds a cmsghdr data structure for a pkt_info
    81 // with unspecified IP address and the outgoing
     82// with specified optional IP address and/or the outgoing
    8283// interface index set to oif.
    8384// This function respects msg->msg_controllen.
     
    8586
    8687int
    87 cmsghdr_build_oif(msghdr *msg, cmsghdr *cmsg, uint16_t oif);
     88cmsghdr_build_oif(msghdr *msg, cmsghdr *cmsg, const hostaddress *own_addr, uint16_t oif);
    8889
    8990void
    90 set_ancillary_data(struct msghdr *msg, int rao, uint16_t oif = 0, int hlim = 0);
     91set_ancillary_data(struct msghdr *msg, int rao, const hostaddress *own_addr= NULL, uint16_t oif = 0, int hlim = 0);
    9192
    9293void
  • protlib/branches/20090723-multicast/src/messages.cpp

    r3675 r4211  
    8080        "TPoverUDS",
    8181        "QoS NSLP Client API over UDS",
     82        "Mobility Service",
    8283        "(INVALID)"
    8384}; // end qaddr_string
     
    9192        "InfoMsg",
    9293        "RoutingMsg",
    93         "APIMsg"
     94        "APIMsg",
     95        "MobilityMsg"
    9496}; // end type_string
    9597
  • protlib/branches/20090723-multicast/src/tp_over_sctp.cpp

    r3675 r4211  
    7171// inherited from TP
    7272void
    73 TPoverSCTP::send(NetMsg *msg, const address &in_addr, bool use_existing_connection)
     73TPoverSCTP::send(NetMsg *msg, const address &in_addr, bool use_existing_connection, const address *local_addr)
    7474{
    7575        if (msg == NULL) {
  • protlib/branches/20090723-multicast/src/tp_over_tls_tcp.cpp

    r3675 r4211  
    381381 */
    382382void
    383 TPoverTLS_TCP::send(NetMsg* netmsg, const address& in_addr, bool use_existing_connection)
     383TPoverTLS_TCP::send(NetMsg* netmsg, const address& in_addr, bool use_existing_connection, const address *local_addr)
    384384{
    385385  if (netmsg == NULL) {
  • protlib/branches/20090723-multicast/src/tp_over_udp.cpp

    r4198 r4211  
    8484
    8585/** generates an internal TPoverUDP message to send a NetMsg to the network
     86 * @param netmsg    the message buffer that should be sent
     87 * @param in_addr   destination address
     88 * @param use_exisiting_connection whether establishing a new connection is allowed (not applicable here)
     89 * @param local_addr source address to use
    8690 *
    8791 *  - the sending thread will call TPoverUDP::udpsend()
     
    8993 *  @note the netmsg is deleted by the send() method when it is not used anymore
    9094 */
    91 void TPoverUDP::send (NetMsg * netmsg, const address & in_addr, bool use_existing_connection)
     95void
     96TPoverUDP::send (NetMsg * netmsg, const address & in_addr, bool use_existing_connection, const address *local_addr)
    9297{
    9398
    9499  appladdress* addr = NULL;
    95100  addr= dynamic_cast<appladdress*>(in_addr.copy());
     101  const hostaddress *own_addr = NULL;
     102  if (local_addr)
     103    own_addr = dynamic_cast<const hostaddress *>(local_addr);
    96104 
    97105  if (!addr) return;
    98106 
    99107  // Do it independently from master thread
    100   udpsend(netmsg, addr);
     108  udpsend(netmsg, addr, own_addr);
    101109
    102110}
     
    110118 */
    111119void
    112 TPoverUDP::udpsend (NetMsg * netmsg, appladdress * addr)
     120TPoverUDP::udpsend (NetMsg * netmsg, appladdress * addr, const hostaddress *local_addr)
    113121{
    114122#ifndef _NO_LOGGING
     
    180188
    181189  // fill msghdr.msg_control
    182   util::set_ancillary_data(&header, rao, oif, hop_limit);
     190  util::set_ancillary_data(&header, rao, local_addr, oif, hop_limit);
    183191
    184192#ifndef _NO_LOGGING
  • protlib/branches/20090723-multicast/src/tp_over_uds.cpp

    r3675 r4211  
    300300 */
    301301void
    302 TPoverUDS::send(NetMsg* netmsg, const address& in_addr, bool use_existing_connection)
     302TPoverUDS::send(NetMsg* netmsg, const address& in_addr, bool use_existing_connection, const address *local_addr)
    303303{
    304304    if (netmsg == NULL) {
  • protlib/branches/20090723-multicast/src/tp_queryencap.cpp

    r4107 r4211  
    8888
    8989void
    90 TPqueryEncap::send (NetMsg * netmsg, const address & addr_in, bool use_existing_connection)
     90TPqueryEncap::send (NetMsg * netmsg, const address & addr_in, bool use_existing_connection, const address *local_addr)
    9191{
    9292  appladdress* addr = NULL;
    9393  addr = dynamic_cast<appladdress*>(addr_in.copy());
     94  const hostaddress *own_addr = NULL;
     95  if (local_addr)
     96    own_addr = dynamic_cast<const hostaddress *>(local_addr);
    9497  // we can safely ignore the use_existing_connection attribute since q-mode is connectionless
    95   udpsend(netmsg, addr);
     98  udpsend(netmsg, addr, own_addr);
    9699}
    97100
     
    201204 */
    202205void
    203 TPqueryEncap::udpsend(NetMsg *netmsg, appladdress *addr)
     206TPqueryEncap::udpsend(NetMsg *netmsg, appladdress *addr, const hostaddress *own_addr)
    204207{
    205208  assert( netmsg != NULL );
     
    283286
    284287  // this sets msg.msg_control and msg.msg_controllen
    285   util::set_ancillary_data(&msg, rao, oif, hop_limit);
     288  util::set_ancillary_data(&msg, rao, own_addr, oif, hop_limit);
    286289
    287290  /*
     
    666669           
    667670            // register incoming interface of query, this may be carried in the responder cookie later
     671            // please note that interface index is still too coarse in case of mobility if you have
     672            // different and changing addresses (Care-of addresses) at the same interface
    668673            peer_addr->set_if_index(if_nametoindex (m->indev_name));
    669674
     
    981986
    982987              // register incoming interface of query, this may be carried in the responder cookie later
     988              // please note that interface index is still too coarse in case of mobility if you have
     989              // different and changing addresses (Care-of addresses) at the same interface
    983990              peer_addr->set_if_index(if_nametoindex (m->indev_name));
    984991             
  • protlib/branches/20090723-multicast/test/old-tests

    • Property svn:mergeinfo
      •  

        old new  
        1 /protlib/trunk/test/old-tests:4161
         1/protlib/branches/20081127-merge-mobility-mk3/test/old-tests:3695-4208
         2/protlib/branches/laier-mobility/test/old-tests:3056-3181
         3/protlib/trunk/test/old-tests:4153-4210
  • protlib/branches/20090723-multicast/test/test_tp_over_xyz.cpp

    r3599 r4211  
    296296
    297297            // invoke send method on TP thread
    298             tpthread.get_thread_object()->send(datamsg, destinationaddr, false);
     298            tpthread.get_thread_object()->send(datamsg, destinationaddr, NULL, false);
    299299
    300300            EVLog(methodname, "message sent");
Note: See TracChangeset for help on using the changeset viewer.