Hello Juha, On 12/15/2011 01:22 PM, Juha Heinanen wrote: >> Just realized that lcr module does not support IPv6 yet. Is there >> already any work going on here? Otherwise we'd take this task over. > > i don't know of such work. if you decide to do it, try to not cause any > performance hit for current ipv4 usage.
Please find attached the patch against git master, courtesy of my colleague Richard Fuchs <rfuchs at sipwise.com>. Please review and apply if acceptable. Andreas
diff --git a/modules/lcr/hash.c b/modules/lcr/hash.c index 4e24c94..2082ad8 100644 --- a/modules/lcr/hash.c +++ b/modules/lcr/hash.c @@ -88,7 +88,7 @@ int get_gw_index(struct gw_info *gws, unsigned int gw_id, { unsigned short gw_count, i; - gw_count = gws[0].ip_addr; + gw_count = gws[0].ip_addr.u.addr32[0]; for (i = 1; i <= gw_count; i++) { if (gws[i].gw_id == gw_id) { diff --git a/modules/lcr/lcr_mod.c b/modules/lcr/lcr_mod.c index dac5c7d..8f8d373 100644 --- a/modules/lcr/lcr_mod.c +++ b/modules/lcr/lcr_mod.c @@ -786,10 +786,11 @@ static int comp_gws(const void *_g1, const void *_g2) struct gw_info *g1 = (struct gw_info *)_g1; struct gw_info *g2 = (struct gw_info *)_g2; - if (g1->ip_addr < g2->ip_addr) return -1; - if (g1->ip_addr > g2->ip_addr) return 1; - - return 0; + if (g1->ip_addr.af < g2->ip_addr.af) return -1; + if (g1->ip_addr.af > g2->ip_addr.af) return 1; + if (g1->ip_addr.len < g2->ip_addr.len) return -1; + if (g1->ip_addr.len > g2->ip_addr.len) return 1; + return memcmp(g1->ip_addr.u.addr, g2->ip_addr.u.addr, g1->ip_addr.len); } @@ -798,7 +799,7 @@ static int comp_gws(const void *_g1, const void *_g2) */ static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int gw_id, char *gw_name, unsigned int gw_name_len, - unsigned int scheme, unsigned int ip_addr, + unsigned int scheme, struct ip_addr *ip_addr, unsigned int port, unsigned int transport, char *params, unsigned int params_len, char *hostname, unsigned int hostname_len, @@ -810,7 +811,7 @@ static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int gw_id, if (gw_name_len) memcpy(&(gws[i].gw_name[0]), gw_name, gw_name_len); gws[i].gw_name_len = gw_name_len; gws[i].scheme = scheme; - gws[i].ip_addr = ip_addr; + gws[i].ip_addr = *ip_addr; gws[i].port = port; gws[i].transport = transport; if (params_len) memcpy(&(gws[i].params[0]), params, params_len); @@ -885,10 +886,11 @@ int reload_tables() tag_len, prefix_len, from_uri_len, stopper, enabled, flags, gw_cnt, hostname_len, params_len, defunct_until, null_gw_ip_addr, priority, weight, tmp; - struct in_addr ip_addr; + struct in_addr in_addr; + struct ip_addr ip_addr, *ip_p; uri_type scheme; uri_transport transport; - char *gw_name, *ip_string, *hostname, *tag, *prefix, *from_uri, *params; + char *gw_name, *hostname, *tag, *prefix, *from_uri, *params; db1_res_t* res = NULL; db_row_t* row; db_key_t key_cols[1]; @@ -900,6 +902,7 @@ int reload_tables() pcre *from_uri_re; struct gw_info *gws, *gw_pt_tmp; struct rule_info **rules, **rule_pt_tmp; + str ip_string; key_cols[0] = &lcr_id_col; op[0] = OP_EQ; @@ -1152,14 +1155,32 @@ int reload_tables() goto err; } if (VAL_NULL(ROW_VALUES(row) + 1)) { - ip_string = (char *)0; - ip_addr.s_addr = 0; + ip_string.s = (char *)0; + ip_addr.af = 0; + ip_addr.len = 0; null_gw_ip_addr = 1; } else { - ip_string = (char *)VAL_STRING(ROW_VALUES(row) + 1); - if (inet_aton(ip_string, &ip_addr) == 0) { + ip_string.s = (char *)VAL_STRING(ROW_VALUES(row) + 1); + ip_string.len = strlen(ip_string.s); + if ((ip_p = str2ip(&ip_string))) { + /* 123.123.123.123 */ + ip_addr = *ip_p; + } +#ifdef USE_IPV6 + else if ((ip_p = str2ip6(&ip_string))) { + /* fe80::123:4567:89ab:cdef and [fe80::123:4567:89ab:cdef] */ + ip_addr = *ip_p; + } +#endif + else if (inet_aton(ip_string.s, &in_addr) == 0) { + /* backwards compatibility for integer or hex notations */ + ip_addr.u.addr32[0] = in_addr.s_addr; + ip_addr.af = AF_INET; + ip_addr.len = 4; + } + else { LM_ERR("lcr_gw ip_addr <%s> at row <%u> is invalid\n", - ip_string, i); + ip_string.s, i); goto err; } } @@ -1233,7 +1254,7 @@ int reload_tables() goto err; } if (VAL_NULL(ROW_VALUES(row) + 6)) { - if (ip_string == 0) { + if (ip_string.s == 0) { LM_ERR("lcr_gw gw ip_addr and hostname are both null " "at row <%u>\n", i); goto err; @@ -1307,9 +1328,9 @@ int reload_tables() } gw_cnt++; if (!insert_gw(gws, gw_cnt, gw_id, gw_name, gw_name_len, - scheme, (unsigned int)ip_addr.s_addr, port, + scheme, &ip_addr, port, transport, params, params_len, hostname, - hostname_len, ip_string, strip, prefix, prefix_len, + hostname_len, ip_string.s, strip, prefix, prefix_len, tag, tag_len, flags, defunct_until)) { goto err; } @@ -1319,7 +1340,7 @@ int reload_tables() res = NULL; qsort(&(gws[1]), gw_cnt, sizeof(struct gw_info), comp_gws); - gws[0].ip_addr = gw_cnt; + gws[0].ip_addr.u.addr32[0] = gw_cnt; gws[0].port = null_gw_ip_addr; /* Reload targets */ @@ -1438,7 +1459,7 @@ inline int encode_avp_value(char *value, unsigned int gw_index, uri_type scheme, unsigned int strip, char *prefix, unsigned int prefix_len, char *tag, unsigned int tag_len, - unsigned int ip_addr, char *hostname, + struct ip_addr *ip_addr, char *hostname, unsigned int hostname_len, unsigned int port, char *params, unsigned int params_len, uri_transport transport, unsigned int flags) @@ -1467,10 +1488,17 @@ inline int encode_avp_value(char *value, unsigned int gw_index, uri_type scheme, append_str(at, tag, tag_len); append_chr(at, '|'); /* ip_addr */ - if (ip_addr > 0) { - string = int2str(ip_addr, &len); + if (ip_addr->af == AF_INET && ip_addr->u.addr32[0] > 0) { + string = int2str(ip_addr->u.addr32[0], &len); append_str(at, string, len); } +#ifdef USE_IPV6 + else if (ip_addr->af == AF_INET6 && !ip_addr_any(ip_addr)) { + append_chr(at, '['); + at += ip6tosbuf(ip_addr->u.addr, at, MAX_URI_LEN - (at - value)); + append_chr(at, ']'); + } +#endif append_chr(at, '|'); /* hostname */ append_str(at, hostname, hostname_len); @@ -1496,12 +1524,13 @@ inline int encode_avp_value(char *value, unsigned int gw_index, uri_type scheme, inline int decode_avp_value(char *value, unsigned int *gw_index, str *scheme, unsigned int *strip, str *prefix, str *tag, - unsigned int *addr, str *hostname, str *port, + struct ip_addr *addr, str *hostname, str *port, str *params, str *transport, unsigned int *flags) { unsigned int u; str s; char *sep; + struct ip_addr *ip; /* gw index */ s.s = value; @@ -1562,9 +1591,20 @@ inline int decode_avp_value(char *value, unsigned int *gw_index, str *scheme, } s.len = sep - s.s; if (s.len > 0) { - str2int(&s, addr); + if ((ip = str2ip(&s)) != NULL) + *addr = *ip; +#ifdef USE_IPV6 + else if ((ip = str2ip6(&s)) != NULL) + *addr = *ip; +#endif + else { + str2int(&s, &u); + addr->af = AF_INET; + addr->len = 4; + addr->u.addr32[0] = u; + } } else { - *addr = 0; + addr->af = 0; } /* hostname */ hostname->s = sep + 1; @@ -1659,7 +1699,7 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws, tag_len = gws[index].tag_len; if (5 /* gw_index */ + 5 /* scheme */ + 4 /* strip */ + prefix_len + tag_len + 1 /* @ */ + - ((hostname_len > 15)?hostname_len:15) + 6 /* port */ + + ((hostname_len > IP6_MAX_STR_SIZE+2)?hostname_len:IP6_MAX_STR_SIZE+2) + 6 /* port */ + params_len /* params */ + 15 /* transport */ + 10 /* flags */ + 7 /* separators */ > MAX_URI_LEN) { LM_ERR("too long AVP value\n"); @@ -1669,7 +1709,7 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws, encode_avp_value(encoded_value, index, gws[index].scheme, strip, gws[index].prefix, prefix_len, gws[index].tag, tag_len, - gws[index].ip_addr, + &gws[index].ip_addr, gws[index].hostname, hostname_len, gws[index].port, gws[index].params, params_len, gws[index].transport, gws[index].flags); @@ -1834,7 +1874,7 @@ static int load_gws(struct sip_msg* _m, int argc, action_u_t argv[]) /* Generate Request-URI and Destination URI */ static int generate_uris(struct sip_msg* _m, char *r_uri, str *r_uri_user, unsigned int *r_uri_len, char *dst_uri, - unsigned int *dst_uri_len, unsigned int *addr, + unsigned int *dst_uri_len, struct ip_addr *addr, unsigned int *gw_index, unsigned int *flags, str *tag) { @@ -1844,7 +1884,6 @@ static int generate_uris(struct sip_msg* _m, char *r_uri, str *r_uri_user, tmp_tag; char *at; unsigned int strip; - struct ip_addr a; gu_avp = search_first_avp(gw_uri_avp_type, gw_uri_avp, &gw_uri_val, 0); @@ -1854,18 +1893,15 @@ static int generate_uris(struct sip_msg* _m, char *r_uri, str *r_uri_user, &tmp_tag, addr, &hostname, &port, ¶ms, &transport, flags); - if (*addr > 0) { - a.af = AF_INET; - a.len = 4; - a.u.addr32[0] = *addr; - addr_str.s = ip_addr2a(&a); + if (addr->af != 0) { + addr_str.s = ip_addr2a(addr); addr_str.len = strlen(addr_str.s); } else { addr_str.len = 0; } if (scheme.len + r_uri_user->len - strip + prefix.len + 1 /* @ */ + - ((hostname.len > 15)?hostname.len:15) + 1 /* : */ + + ((hostname.len > IP6_MAX_STR_SIZE+2)?hostname.len:IP6_MAX_STR_SIZE+2) + 1 /* : */ + port.len + params.len + transport.len + 1 /* null */ > MAX_URI_LEN) { LM_ERR("too long Request URI or DST URI\n"); return -1; @@ -1901,7 +1937,11 @@ static int generate_uris(struct sip_msg* _m, char *r_uri, str *r_uri_user, *r_uri_len = at - r_uri; at = dst_uri; append_str(at, scheme.s, scheme.len); + if (addr->af == AF_INET6) + append_chr(at, '['); append_str(at, addr_str.s, addr_str.len); + if (addr->af == AF_INET6) + append_chr(at, ']'); if (port.len > 0) { append_chr(at, ':'); append_str(at, port.s, port.len); @@ -1915,7 +1955,11 @@ static int generate_uris(struct sip_msg* _m, char *r_uri, str *r_uri_user, /* either ip_addr or hostname specified: place the given one in r-uri and leave dst-uri empty */ if (addr_str.len > 0) { + if (addr->af == AF_INET6) + append_chr(at, '['); append_str(at, addr_str.s, addr_str.len); + if (addr->af == AF_INET6) + append_chr(at, ']'); } else { append_str(at, hostname.s, hostname.len); } @@ -1990,7 +2034,7 @@ static int defunct_gw(struct sip_msg* _m, char *_defunct_period, char *_s2) return -1; } gw_index = index_val.n; - if ((gw_index < 1) || (gw_index > gws[0].ip_addr)) { + if ((gw_index < 1) || (gw_index > gws[0].ip_addr.u.addr32[0])) { LM_ERR("gw index <%u> is out of bounds\n", gw_index); return -1; } @@ -2023,8 +2067,9 @@ static int next_gw(struct sip_msg* _m, char* _s1, char* _s2) int rval; str uri_str, tag_str; char tag[MAX_TAG_LEN]; - unsigned int flags, r_uri_len, dst_uri_len, addr, gw_index; + unsigned int flags, r_uri_len, dst_uri_len, gw_index; char r_uri[MAX_URI_LEN], dst_uri[MAX_URI_LEN]; + struct ip_addr addr; tag_str.s = &(tag[0]); @@ -2103,7 +2148,7 @@ static int next_gw(struct sip_msg* _m, char* _s1, char* _s2) delete_avp(defunct_gw_avp_type, defunct_gw_avp); val.n = gw_index; add_avp(defunct_gw_avp_type, defunct_gw_avp, val); - LM_DBG("added defunct_gw_avp <%u>", addr); + LM_DBG("added defunct_gw_avp <%u>", addr.u.addr32[0]); } return 1; @@ -2114,7 +2159,7 @@ static int next_gw(struct sip_msg* _m, char* _s1, char* _s2) * Checks if request comes from ip address of a gateway */ static int do_from_gw(struct sip_msg* _m, unsigned int lcr_id, - unsigned int src_addr, uri_transport transport) + struct ip_addr *src_addr, uri_transport transport) { struct gw_info *res, gw, *gws; int_str val; @@ -2128,8 +2173,8 @@ static int do_from_gw(struct sip_msg* _m, unsigned int lcr_id, } /* Search for gw ip address */ - gw.ip_addr = src_addr; - res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr, + gw.ip_addr = *src_addr; + res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr.u.addr32[0], sizeof(struct gw_info), comp_gws); /* Store tag and flags and return result */ @@ -2164,7 +2209,6 @@ static int from_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2) { int lcr_id; char *tmp; - unsigned int src_addr; uri_transport transport; /* Get and check parameter value */ @@ -2178,12 +2222,11 @@ static int from_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2) return -1; } - /* Get source address and transport protocol */ - src_addr = _m->rcv.src_ip.u.addr32[0]; + /* Get transport protocol */ transport = _m->rcv.proto; /* Do test */ - return do_from_gw(_m, lcr_id, src_addr, transport); + return do_from_gw(_m, lcr_id, &_m->rcv.src_ip, transport); } @@ -2194,7 +2237,7 @@ static int from_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2) static int from_gw_3(struct sip_msg* _m, char* _lcr_id, char* _addr, char* _transport) { - unsigned int src_addr; + struct ip_addr src_addr; int lcr_id; char *tmp; struct ip_addr *ip; @@ -2213,11 +2256,15 @@ static int from_gw_3(struct sip_msg* _m, char* _lcr_id, char* _addr, } addr_str.s = _addr; addr_str.len = strlen(_addr); - if ((ip = str2ip(&addr_str)) == NULL) { + if ((ip = str2ip(&addr_str)) != NULL) + src_addr = *ip; +#ifdef USE_IPV6 + else if ((ip = str2ip6(&addr_str)) != NULL) + src_addr = *ip; +#endif + else { LM_ERR("addr param value %s is not an IP address\n", _addr); return -1; - } else { - src_addr = ip->u.addr32[0]; } transport = strtol(_transport, &tmp, 10); if ((tmp == 0) || (*tmp) || (tmp == _transport)) { @@ -2230,7 +2277,7 @@ static int from_gw_3(struct sip_msg* _m, char* _lcr_id, char* _addr, } /* Do test */ - return do_from_gw(_m, lcr_id, src_addr, transport); + return do_from_gw(_m, lcr_id, &src_addr, transport); } @@ -2240,14 +2287,13 @@ static int from_gw_3(struct sip_msg* _m, char* _lcr_id, char* _addr, */ static int from_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2) { - unsigned int src_addr, i; + unsigned int i; uri_transport transport; - src_addr = _m->rcv.src_ip.u.addr32[0]; transport = _m->rcv.proto; for (i = 1; i <= lcr_count_param; i++) { - if (do_from_gw(_m, i, src_addr, transport) == 1) { + if (do_from_gw(_m, i, &_m->rcv.src_ip, transport) == 1) { return i; } } @@ -2261,20 +2307,24 @@ static int from_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2) */ static int from_any_gw_2(struct sip_msg* _m, char* _addr, char* _transport) { - unsigned int i, src_addr; + unsigned int i; char *tmp; - struct ip_addr *ip; + struct ip_addr *ip, src_addr; str addr_str; uri_transport transport; /* Get and check parameter values */ addr_str.s = _addr; addr_str.len = strlen(_addr); - if ((ip = str2ip(&addr_str)) == NULL) { + if ((ip = str2ip(&addr_str)) != NULL) + src_addr = *ip; +#ifdef USE_IPV6 + else if ((ip = str2ip6(&addr_str)) != NULL) + src_addr = *ip; +#endif + else { LM_ERR("addr param value %s is not an IP address\n", _addr); return -1; - } else { - src_addr = ip->u.addr32[0]; } transport = strtol(_transport, &tmp, 10); if ((tmp == 0) || (*tmp) || (tmp == _transport)) { @@ -2288,7 +2338,7 @@ static int from_any_gw_2(struct sip_msg* _m, char* _addr, char* _transport) /* Do test */ for (i = 1; i <= lcr_count_param; i++) { - if (do_from_gw(_m, i, src_addr, transport) == 1) { + if (do_from_gw(_m, i, &src_addr, transport) == 1) { return i; } } @@ -2300,7 +2350,7 @@ static int from_any_gw_2(struct sip_msg* _m, char* _addr, char* _transport) * Checks if in-dialog request goes to ip address of a gateway. */ static int do_to_gw(struct sip_msg* _m, unsigned int lcr_id, - unsigned int dst_addr, uri_transport transport) + struct ip_addr *dst_addr, uri_transport transport) { struct gw_info *res, gw, *gws; @@ -2313,8 +2363,8 @@ static int do_to_gw(struct sip_msg* _m, unsigned int lcr_id, } /* Search for gw ip address */ - gw.ip_addr = dst_addr; - res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr, + gw.ip_addr = *dst_addr; + res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr.u.addr32[0], sizeof(struct gw_info), comp_gws); /* Return result */ @@ -2339,8 +2389,7 @@ static int to_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2) { int lcr_id; char *tmp; - unsigned int dst_addr; - struct ip_addr *ip; + struct ip_addr *ip, dst_addr; uri_transport transport; /* Get and check parameter value */ @@ -2359,22 +2408,26 @@ static int to_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2) LM_ERR("while parsing Request-URI\n"); return -1; } - if (_m->parsed_uri.host.len > 15) { + if (_m->parsed_uri.host.len > IP6_MAX_STR_SIZE+2) { LM_DBG("request is not going to gw " "(Request-URI host is not an IP address)\n"); return -1; } - if ((ip = str2ip(&(_m->parsed_uri.host))) == NULL) { + if ((ip = str2ip(&(_m->parsed_uri.host))) != NULL) + dst_addr = *ip; +#ifdef USE_IPV6 + else if ((ip = str2ip6(&(_m->parsed_uri.host))) != NULL) + dst_addr = *ip; +#endif + else { LM_DBG("request is not going to gw " "(Request-URI host is not an IP address)\n"); return -1; - } else { - dst_addr = ip->u.addr32[0]; } transport = _m->parsed_uri.proto; /* Do test */ - return do_to_gw(_m, lcr_id, dst_addr, transport); + return do_to_gw(_m, lcr_id, &dst_addr, transport); } @@ -2387,8 +2440,7 @@ static int to_gw_3(struct sip_msg* _m, char* _lcr_id, char* _addr, { int lcr_id; char *tmp; - unsigned int dst_addr; - struct ip_addr *ip; + struct ip_addr *ip, dst_addr; str addr_str; uri_transport transport; @@ -2404,11 +2456,15 @@ static int to_gw_3(struct sip_msg* _m, char* _lcr_id, char* _addr, } addr_str.s = _addr; addr_str.len = strlen(_addr); - if ((ip = str2ip(&addr_str)) == NULL) { + if ((ip = str2ip(&addr_str)) != NULL) + dst_addr = *ip; +#ifdef USE_IPV6 + else if ((ip = str2ip(&addr_str)) != NULL) + dst_addr = *ip; +#endif + else { LM_ERR("addr param value %s is not an IP address\n", _addr); return -1; - } else { - dst_addr = ip->u.addr32[0]; } transport = strtol(_transport, &tmp, 10); if ((tmp == 0) || (*tmp) || (tmp == _transport)) { @@ -2421,7 +2477,7 @@ static int to_gw_3(struct sip_msg* _m, char* _lcr_id, char* _addr, } /* Do test */ - return do_to_gw(_m, lcr_id, dst_addr, transport); + return do_to_gw(_m, lcr_id, &dst_addr, transport); } @@ -2431,8 +2487,8 @@ static int to_gw_3(struct sip_msg* _m, char* _lcr_id, char* _addr, */ static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2) { - unsigned int dst_addr, i; - struct ip_addr *ip; + unsigned int i; + struct ip_addr *ip, dst_addr; uri_transport transport; /* Get destination address and transport protocol from R-URI */ @@ -2440,23 +2496,27 @@ static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2) LM_ERR("while parsing Request-URI\n"); return -1; } - if (_m->parsed_uri.host.len > 15) { + if (_m->parsed_uri.host.len > IP6_MAX_STR_SIZE+2) { LM_DBG("request is not going to gw " "(Request-URI host is not an IP address)\n"); return -1; } - if ((ip = str2ip(&(_m->parsed_uri.host))) == NULL) { + if ((ip = str2ip(&(_m->parsed_uri.host))) != NULL) + dst_addr = *ip; +#ifdef USE_IPV6 + else if ((ip = str2ip6(&(_m->parsed_uri.host))) != NULL) + dst_addr = *ip; +#endif + else { LM_DBG("request is not going to gw " "(Request-URI host is not an IP address)\n"); return -1; - } else { - dst_addr = ip->u.addr32[0]; } transport = _m->parsed_uri.proto; /* Do test */ for (i = 1; i <= lcr_count_param; i++) { - if (do_to_gw(_m, i, dst_addr, transport) == 1) { + if (do_to_gw(_m, i, &dst_addr, transport) == 1) { return i; } } @@ -2470,20 +2530,24 @@ static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2) */ static int to_any_gw_2(struct sip_msg* _m, char* _addr, char* _transport) { - unsigned int i, dst_addr; + unsigned int i; char *tmp; - struct ip_addr *ip; + struct ip_addr *ip, dst_addr; uri_transport transport; str addr_str; /* Get and check parameter values */ addr_str.s = _addr; addr_str.len = strlen(_addr); - if ((ip = str2ip(&addr_str)) == NULL) { + if ((ip = str2ip(&addr_str)) != NULL) + dst_addr = *ip; +#ifdef USE_IPV6 + if ((ip = str2ip6(&addr_str)) != NULL) + dst_addr = *ip; +#endif + else { LM_ERR("addr param value %s is not an IP address\n", _addr); return -1; - } else { - dst_addr = ip->u.addr32[0]; } transport = strtol(_transport, &tmp, 10); if ((tmp == 0) || (*tmp) || (tmp == _transport)) { @@ -2497,7 +2561,7 @@ static int to_any_gw_2(struct sip_msg* _m, char* _addr, char* _transport) /* Do test */ for (i = 1; i <= lcr_count_param; i++) { - if (do_to_gw(_m, i, dst_addr, transport) == 1) { + if (do_to_gw(_m, i, &dst_addr, transport) == 1) { return i; } } diff --git a/modules/lcr/lcr_mod.h b/modules/lcr/lcr_mod.h index 16c0b16..e544f68 100644 --- a/modules/lcr/lcr_mod.h +++ b/modules/lcr/lcr_mod.h @@ -42,6 +42,7 @@ #include "../../lib/kmi/mi.h" #include "../../locking.h" #include "../../parser/parse_uri.h" +#include "../../ip_addr.h" #define MAX_PREFIX_LEN 16 #define MAX_URI_LEN 256 @@ -84,7 +85,7 @@ struct gw_info { char gw_name[MAX_NAME_LEN]; unsigned short gw_name_len; uri_type scheme; - unsigned int ip_addr; + struct ip_addr ip_addr; char hostname[MAX_HOST_LEN]; unsigned short hostname_len; unsigned int port; diff --git a/modules/lcr/lcr_rpc.c b/modules/lcr/lcr_rpc.c index b32b697..f70c042 100644 --- a/modules/lcr/lcr_rpc.c +++ b/modules/lcr/lcr_rpc.c @@ -72,7 +72,7 @@ static void dump_gws(rpc_t* rpc, void* c) gws = gw_pt[j]; - for (i = 1; i <= gws[0].ip_addr; i++) { + for (i = 1; i <= gws[0].ip_addr.u.addr32[0]; i++) { if (rpc->add(c, "{", &st) < 0) return; rpc->struct_add(st, "d", "lcr_id", j); rpc->struct_add(st, "d", "gw_id", gws[i].gw_id); @@ -85,11 +85,22 @@ static void dump_gws(rpc_t* rpc, void* c) } else { rpc->struct_add(st, "s", "scheme", "sips"); } - rpc->struct_printf(st, "ip_addr", "%d.%d.%d.%d", - (gws[i].ip_addr << 24) >> 24, - ((gws[i].ip_addr >> 8) << 24) >> 24, - ((gws[i].ip_addr >> 16) << 24) >> 24, - gws[i].ip_addr >> 24); + if (gws[i].ip_addr.af == AF_INET) + rpc->struct_printf(st, "ip_addr", "%d.%d.%d.%d", + gws[i].ip_addr.u.addr32[0], + gws[i].ip_addr.u.addr32[1], + gws[i].ip_addr.u.addr32[2], + gws[i].ip_addr.u.addr32[3]); + else /* AF_INET6 */ + rpc->struct_printf(st, "ip_addr", "%x:%x:%x:%x:%x:%x:%x:%x", + gws[i].ip_addr.u.addr16[0], + gws[i].ip_addr.u.addr16[1], + gws[i].ip_addr.u.addr16[2], + gws[i].ip_addr.u.addr16[3], + gws[i].ip_addr.u.addr16[4], + gws[i].ip_addr.u.addr16[5], + gws[i].ip_addr.u.addr16[6], + gws[i].ip_addr.u.addr16[7]); hostname.s=gws[i].hostname; hostname.len=gws[i].hostname_len; rpc->struct_add(st, "S", "hostname", &hostname);
signature.asc
Description: OpenPGP digital signature
_______________________________________________ SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list sr-users@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users