Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for subdomain checking in aliases and socket aliases #3458

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cfg.lex
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ CR \n

ANY "any"
ANYCAST ("anycast"|"ANYCAST")
SUBDOMAIN ("subdomain"|"SUBDOMAIN")
FRAG ("frag"|"FRAG")
REUSE_PORT ("reuse_port"|"REUSE_PORT")

Expand Down Expand Up @@ -615,6 +616,7 @@ SPACE [ ]
<INITIAL>{CR} { count();/* return CR;*/ }
<INITIAL>{ANY} { count(); return ANY; }
<INITIAL>{ANYCAST} { count(); return ANYCAST; }
<INITIAL>{SUBDOMAIN} { count(); return SUBDOMAIN; }
<INITIAL>{REUSE_PORT} { count(); return REUSE_PORT; }
<INITIAL>{FRAG} { count(); return FRAG; }
<INITIAL>{SLASH} { count(); return SLASH; }
Expand Down
31 changes: 29 additions & 2 deletions cfg.y
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ struct listen_param {
char *auto_scaling_profile;
} p_tmp;
static void fill_socket_id(struct listen_param *param, struct socket_id *s);
static void fill_alias_socket(struct listen_param *param, struct socket_id *s);

union route_name_var {
int iname;
Expand Down Expand Up @@ -466,6 +467,7 @@ extern int cfg_parse_only_routes;
%token COLON
%token ANY
%token ANYCAST
%token SUBDOMAIN
%token FRAG
%token REUSE_PORT
%token SCRIPTVARERR
Expand All @@ -491,6 +493,7 @@ extern int cfg_parse_only_routes;
%type <sockid> socket_def
%type <sockid> id_lst
%type <sockid> alias_def
%type <sockid> any_alias
%type <sockid> listen_id_def
%type <sockid> phostport phostportrange
%type <intval> proto port any_proto
Expand Down Expand Up @@ -694,7 +697,7 @@ phostportrange: proto COLON MULT { IFOR();
}
;

alias_def: listen_id { IFOR();
any_alias: listen_id { IFOR();
$$=mk_listen_id($1, PROTO_NONE, 0); }
| ANY COLON listen_id { IFOR();
$$=mk_listen_id($3, PROTO_NONE, 0); }
Expand All @@ -707,6 +710,23 @@ alias_def: listen_id { IFOR();
| phostport
;

id_lst_param: SUBDOMAIN { IFOR();
p_tmp.flags |= SI_IS_SUBDOMAIN_ALIAS;
}
;

id_lst_params: id_lst_param
| id_lst_param id_lst_params
;

alias_def: any_alias { $$=$1; }
| any_alias { IFOR();
memset(&p_tmp, 0, sizeof(p_tmp));
} id_lst_params { IFOR();
$$=$1; fill_alias_socket(&p_tmp, $$);
}
;

id_lst: alias_def { IFOR(); $$=$1 ; }
| alias_def id_lst { IFOR(); $$=$1; $$->next=$2; }
;
Expand All @@ -730,6 +750,9 @@ socket_def_param: ANYCAST { IFOR();
| REUSE_PORT { IFOR();
p_tmp.flags |= SI_REUSEPORT;
}
| SUBDOMAIN { IFOR();
p_tmp.flags |= SI_IS_SUBDOMAIN_ALIAS;
}
| USE_WORKERS NUMBER { IFOR();
p_tmp.workers=$2;
}
Expand Down Expand Up @@ -1484,7 +1507,7 @@ assign_stm: LOGLEVEL EQUAL snumber { IFOR();
| ALIAS EQUAL id_lst { IFOR();
for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next)
add_alias(lst_tmp->name, strlen(lst_tmp->name),
lst_tmp->port, lst_tmp->proto);
lst_tmp->port, lst_tmp->proto, lst_tmp->flags);
}
| ALIAS EQUAL error { yyerror("hostname expected (use quotes"
" if the hostname includes config keywords)"); }
Expand Down Expand Up @@ -2771,6 +2794,10 @@ static void fill_socket_id(struct listen_param *param, struct socket_id *s)
}
}

static void fill_alias_socket(struct listen_param *param, struct socket_id *s) {
s->flags |= param->flags;
}

static struct multi_str *new_string(char *s)
{
struct multi_str *ms = pkg_malloc(sizeof(struct multi_str));
Expand Down
2 changes: 1 addition & 1 deletion ip_addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ union sockaddr_union{


enum si_flags { SI_NONE=0, SI_IS_IP=1, SI_IS_LO=2, SI_IS_MCAST=4,
SI_IS_ANYCAST=8, SI_FRAG=16, SI_REUSEPORT=32, SI_INTERNAL=64 };
SI_IS_ANYCAST=8, SI_FRAG=16, SI_REUSEPORT=32, SI_INTERNAL=64, SI_IS_SUBDOMAIN_ALIAS=128 };

struct receive_info {
struct ip_addr src_ip;
Expand Down
4 changes: 2 additions & 2 deletions name_alias.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include <string.h>
#include "name_alias.h"


struct host_alias* aliases=0; /* name aliases list */

struct alias_function* alias_fcts = NULL;
Expand All @@ -40,7 +39,7 @@ struct alias_function* alias_fcts = NULL;
* if proto==0, the alias will match all the protocols
* returns 1 if a new alias was added, 0 if a matching alias was already on
* the list and -1 on error */
int add_alias(char* name, int len, unsigned short port, unsigned short proto)
int add_alias(char* name, int len, unsigned short port, unsigned short proto, enum si_flags flags)
{
struct host_alias* a;

Expand All @@ -63,6 +62,7 @@ int add_alias(char* name, int len, unsigned short port, unsigned short proto)
a->alias.s[len]=0; /* null terminate for easier printing*/
a->port=port;
a->proto=proto;
a->flags=flags;
a->next=aliases;
aliases=a;
return 1;
Expand Down
37 changes: 30 additions & 7 deletions name_alias.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <strings.h>
#include "str.h"
#include "dprint.h"
#include "ip_addr.h"
#include "mem/mem.h"


Expand All @@ -41,6 +42,7 @@ struct host_alias{
str alias;
unsigned short port;
unsigned short proto;
enum si_flags flags;
struct host_alias* next;
};

Expand All @@ -65,17 +67,39 @@ static inline int grep_aliases(char* name, int len, unsigned short port,
{
struct host_alias* a;
struct alias_function *af;
char *name_to_compare, *alias_to_compare;
int len_to_compare, index_offset;

if ((len>2)&&((*name)=='[')&&(name[len-1]==']')){
/* ipv6 reference, skip [] */
name++;
len-=2;
}
for(a=aliases;a;a=a->next)
if ((a->alias.len==len) && ((a->port==0) || (port==0) ||
(a->port==port)) && ((a->proto==0) || (proto==0) ||
(a->proto==proto)) && (strncasecmp(a->alias.s, name, len)==0))
return 1;

for(a=aliases;a;a=a->next) {
if (((a->port==0) || (port==0) || (a->port==port)) &&
((a->proto==0) || (proto==0) || (a->proto==proto))) {
/* Check if the alias is a subdomain alias and if so calculate the index offset to start the comparison
* Given an alias my.domain.com or my.great.domain.com and a subdomain of domain.com the comparison should start at domain.com
* a host of domain.com will also match, if the flag is not set then do a strict comparison
*/
if (a->flags & SI_IS_SUBDOMAIN_ALIAS) {
index_offset = len - a->alias.len;
if (index_offset < 0) // the host we're checking is a shorter len than the alias so no need to compare
continue;

name_to_compare = name + index_offset;
alias_to_compare = a->alias.s;

len_to_compare = a->alias.len;

if (strncasecmp(alias_to_compare, name_to_compare, len_to_compare)==0)
return 1;
} else if (len == a->alias.len && strncasecmp(a->alias.s, name, len)==0) {
return 1;
}
}
}

for( af=alias_fcts ; af ; af=af->next ) {
if ( af->alias_f(name,len,port,proto)>0 )
Expand All @@ -84,9 +108,8 @@ static inline int grep_aliases(char* name, int len, unsigned short port,
return 0;
}


/* adds an alias to the list (only if it isn't already there) */
int add_alias(char* name, int len, unsigned short port, unsigned short proto);
int add_alias(char* name, int len, unsigned short port, unsigned short proto, enum si_flags flags);

/* register a new function for detecting aliases */
int register_alias_fct( is_alias_fct *fct );
Expand Down
10 changes: 5 additions & 5 deletions socket_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ int fix_socket_list(struct socket_info_full **list)
/* check if we got the official name */
if (strcasecmp(he->h_name, si->name.s)!=0){
if (auto_aliases && add_alias(si->name.s, si->name.len,
si->port_no, si->proto)<0){
si->port_no, si->proto, si->flags)<0){
LM_ERR("add_alias failed\n");
}
/* change the official name */
Expand All @@ -684,7 +684,7 @@ int fix_socket_list(struct socket_info_full **list)
/* add the aliases*/
if (auto_aliases) {
for(h=he->h_aliases; h && *h; h++)
if (add_alias(*h, strlen(*h), si->port_no, si->proto)<0){
if (add_alias(*h, strlen(*h), si->port_no, si->proto, si->flags)<0){
LM_ERR("add_alias failed\n");
}
}
Expand Down Expand Up @@ -724,11 +724,11 @@ int fix_socket_list(struct socket_info_full **list)
}else{
/* add the aliases*/
if (add_alias(he->h_name, strlen(he->h_name),
si->port_no, si->proto)<0){
si->port_no, si->proto, si->flags)<0){
LM_ERR("add_alias failed\n");
}
for(h=he->h_aliases; h && *h; h++)
if (add_alias(*h,strlen(*h),si->port_no,si->proto)<0){
if (add_alias(*h,strlen(*h),si->port_no,si->proto, si->flags)<0){
LM_ERR(" add_alias failed\n");
}
}
Expand Down Expand Up @@ -859,7 +859,7 @@ int fix_socket_list(struct socket_info_full **list)
(sl->name.len!=si->name.len)||
(strncmp(sl->name.s, si->name.s, si->name.len)!=0))
)
if (add_alias(sl->name.s,sl->name.len,sl->port_no,sl->proto)<0)
if (add_alias(sl->name.s,sl->name.len,sl->port_no,sl->proto,sl->flags)<0)
LM_ERR(" add_alias failed\n");

/* remove l*/
Expand Down