... | ... |
@@ -111,6 +111,9 @@ int do_action(struct action* a, struct sip_msg* msg) |
111 | 111 |
if (a->type==FORWARD_UDP_T) proto=PROTO_UDP; |
112 | 112 |
#ifdef USE_TCP |
113 | 113 |
else if (a->type==FORWARD_TCP_T) proto= PROTO_TCP; |
114 |
+#endif |
|
115 |
+#ifdef USE_TLS |
|
116 |
+ else if (a->type==FORWARD_TLS_T) proto= PROTO_TLS; |
|
114 | 117 |
#endif |
115 | 118 |
else proto=msg->rcv.proto; |
116 | 119 |
if (a->p1_type==URIHOST_ST){ |
... | ... |
@@ -150,6 +153,9 @@ int do_action(struct action* a, struct sip_msg* msg) |
150 | 153 |
case PROTO_UDP: |
151 | 154 |
#ifdef USE_TCP |
152 | 155 |
case PROTO_TCP: |
156 |
+#endif |
|
157 |
+#ifdef USE_TLS |
|
158 |
+ case PROTO_TLS: |
|
153 | 159 |
#endif |
154 | 160 |
proto=u->proto; |
155 | 161 |
break; |
... | ... |
@@ -224,7 +230,7 @@ int do_action(struct action* a, struct sip_msg* msg) |
224 | 230 |
#ifdef USE_TCP |
225 | 231 |
else{ |
226 | 232 |
/*tcp*/ |
227 |
- ret=tcp_send(msg->buf, msg->len, to, 0); |
|
233 |
+ ret=tcp_send(PROTO_TCP, msg->buf, msg->len, to, 0); |
|
228 | 234 |
} |
229 | 235 |
#endif |
230 | 236 |
} |
... | ... |
@@ -75,6 +75,7 @@ |
75 | 75 |
FORWARD forward |
76 | 76 |
FORWARD_TCP forward_tcp |
77 | 77 |
FORWARD_UDP forward_udp |
78 |
+FORWARD_TLS forward_tls |
|
78 | 79 |
DROP "drop"|"break" |
79 | 80 |
SEND send |
80 | 81 |
SEND_TCP send_tcp |
... | ... |
@@ -209,6 +210,7 @@ EAT_ABLE [\ \t\b\r] |
209 | 210 |
|
210 | 211 |
<INITIAL>{FORWARD} {count(); yylval.strval=yytext; return FORWARD; } |
211 | 212 |
<INITIAL>{FORWARD_TCP} {count(); yylval.strval=yytext; return FORWARD_TCP; } |
213 |
+<INITIAL>{FORWARD_TLS} {count(); yylval.strval=yytext; return FORWARD_TLS; } |
|
212 | 214 |
<INITIAL>{FORWARD_UDP} {count(); yylval.strval=yytext; return FORWARD_UDP; } |
213 | 215 |
<INITIAL>{DROP} { count(); yylval.strval=yytext; return DROP; } |
214 | 216 |
<INITIAL>{SEND} { count(); yylval.strval=yytext; return SEND; } |
... | ... |
@@ -103,6 +103,7 @@ int rt; /* Type of route block for find_export */ |
103 | 103 |
/* keywords */ |
104 | 104 |
%token FORWARD |
105 | 105 |
%token FORWARD_TCP |
106 |
+%token FORWARD_TLS |
|
106 | 107 |
%token FORWARD_UDP |
107 | 108 |
%token SEND |
108 | 109 |
%token SEND_TCP |
... | ... |
@@ -921,6 +922,71 @@ cmd: FORWARD LPAREN host RPAREN { $$=mk_action( FORWARD_T, |
921 | 922 |
| FORWARD_TCP error { $$=0; yyerror("missing '(' or ')' ?"); } |
922 | 923 |
| FORWARD_TCP LPAREN error RPAREN { $$=0; yyerror("bad forward_tcp" |
923 | 924 |
"argument"); } |
925 |
+ | FORWARD_TLS LPAREN host RPAREN { $$=mk_action( FORWARD_TLS_T, |
|
926 |
+ STRING_ST, |
|
927 |
+ NUMBER_ST, |
|
928 |
+ $3, |
|
929 |
+ 0); |
|
930 |
+ } |
|
931 |
+ | FORWARD_TLS LPAREN STRING RPAREN { $$=mk_action( FORWARD_TLS_T, |
|
932 |
+ STRING_ST, |
|
933 |
+ NUMBER_ST, |
|
934 |
+ $3, |
|
935 |
+ 0); |
|
936 |
+ } |
|
937 |
+ | FORWARD_TLS LPAREN ip RPAREN { $$=mk_action( FORWARD_TLS_T, |
|
938 |
+ IP_ST, |
|
939 |
+ NUMBER_ST, |
|
940 |
+ (void*)$3, |
|
941 |
+ 0); |
|
942 |
+ } |
|
943 |
+ | FORWARD_TLS LPAREN host COMMA NUMBER RPAREN { $$=mk_action( |
|
944 |
+ FORWARD_TLS_T, |
|
945 |
+ STRING_ST, |
|
946 |
+ NUMBER_ST, |
|
947 |
+ $3, |
|
948 |
+ (void*)$5); |
|
949 |
+ } |
|
950 |
+ | FORWARD_TLS LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action( |
|
951 |
+ FORWARD_TLS_T, |
|
952 |
+ STRING_ST, |
|
953 |
+ NUMBER_ST, |
|
954 |
+ $3, |
|
955 |
+ (void*)$5); |
|
956 |
+ } |
|
957 |
+ | FORWARD_TLS LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TLS_T, |
|
958 |
+ IP_ST, |
|
959 |
+ NUMBER_ST, |
|
960 |
+ (void*)$3, |
|
961 |
+ (void*)$5); |
|
962 |
+ } |
|
963 |
+ | FORWARD_TLS LPAREN URIHOST COMMA URIPORT RPAREN { |
|
964 |
+ $$=mk_action(FORWARD_TLS_T, |
|
965 |
+ URIHOST_ST, |
|
966 |
+ URIPORT_ST, |
|
967 |
+ 0, |
|
968 |
+ 0); |
|
969 |
+ } |
|
970 |
+ |
|
971 |
+ |
|
972 |
+ | FORWARD_TLS LPAREN URIHOST COMMA NUMBER RPAREN { |
|
973 |
+ $$=mk_action(FORWARD_TLS_T, |
|
974 |
+ URIHOST_ST, |
|
975 |
+ NUMBER_ST, |
|
976 |
+ 0, |
|
977 |
+ (void*)$5); |
|
978 |
+ } |
|
979 |
+ | FORWARD_TLS LPAREN URIHOST RPAREN { |
|
980 |
+ $$=mk_action(FORWARD_TLS_T, |
|
981 |
+ URIHOST_ST, |
|
982 |
+ NUMBER_ST, |
|
983 |
+ 0, |
|
984 |
+ 0); |
|
985 |
+ } |
|
986 |
+ | FORWARD_TLS error { $$=0; yyerror("missing '(' or ')' ?"); } |
|
987 |
+ | FORWARD_TLS LPAREN error RPAREN { $$=0; yyerror("bad forward_tcp" |
|
988 |
+ "argument"); } |
|
989 |
+ |
|
924 | 990 |
| SEND LPAREN host RPAREN { $$=mk_action( SEND_T, |
925 | 991 |
STRING_ST, |
926 | 992 |
NUMBER_ST, |
... | ... |
@@ -176,6 +176,21 @@ struct socket_info* get_send_socket(union sockaddr_union* to, int proto) |
176 | 176 |
} |
177 | 177 |
break; |
178 | 178 |
#endif |
179 |
+#ifdef USE_TLS |
|
180 |
+ case PROTO_TLS: |
|
181 |
+ switch(to->s.sa_family){ |
|
182 |
+ /* FIXME */ |
|
183 |
+ case AF_INET: send_sock=sendipv4_tls; |
|
184 |
+ break; |
|
185 |
+#ifdef USE_IPV6 |
|
186 |
+ case AF_INET6: send_sock=sendipv6_tls; |
|
187 |
+ break; |
|
188 |
+#endif |
|
189 |
+ default: LOG(L_ERR, "get_send_socket: BUG: don't know how" |
|
190 |
+ " to forward to af %d\n", to->s.sa_family); |
|
191 |
+ } |
|
192 |
+ break; |
|
193 |
+#endif /* USE_TLS */ |
|
179 | 194 |
case PROTO_UDP: |
180 | 195 |
if ((bind_address==0)||(to->s.sa_family!=bind_address->address.af)|| |
181 | 196 |
(bind_address->proto!=PROTO_UDP)){ |
... | ... |
@@ -482,7 +497,11 @@ int forward_reply(struct sip_msg* msg) |
482 | 497 |
|
483 | 498 |
|
484 | 499 |
#ifdef USE_TCP |
485 |
- if (proto==PROTO_TCP){ |
|
500 |
+ if (proto==PROTO_TCP |
|
501 |
+#ifdef USE_TLS |
|
502 |
+ || proto==PROTO_TLS |
|
503 |
+#endif |
|
504 |
+ ){ |
|
486 | 505 |
/* find id in i param if it exists */ |
487 | 506 |
if (msg->via1->i&&msg->via1->i->value.s){ |
488 | 507 |
s=msg->via1->i->value.s; |
... | ... |
@@ -106,14 +106,30 @@ static inline int msg_send( struct socket_info* send_sock, int proto, |
106 | 106 |
" support is disabled\n"); |
107 | 107 |
goto error; |
108 | 108 |
}else{ |
109 |
- if (tcp_send(buf, len, to, id)<0){ |
|
109 |
+ if (tcp_send(proto, buf, len, to, id)<0){ |
|
110 | 110 |
STATS_TX_DROPS; |
111 | 111 |
LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n"); |
112 | 112 |
goto error; |
113 | 113 |
} |
114 | 114 |
} |
115 | 115 |
} |
116 |
-#endif |
|
116 |
+#ifdef USE_TLS |
|
117 |
+ else if (proto==PROTO_TLS){ |
|
118 |
+ if (tls_disable){ |
|
119 |
+ STATS_TX_DROPS; |
|
120 |
+ LOG(L_WARN, "msg_send: WARNING: attempt to send on tls and tls" |
|
121 |
+ " support is disabled\n"); |
|
122 |
+ goto error; |
|
123 |
+ }else{ |
|
124 |
+ if (tcp_send(proto, buf, len, to, id)<0){ |
|
125 |
+ STATS_TX_DROPS; |
|
126 |
+ LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n"); |
|
127 |
+ goto error; |
|
128 |
+ } |
|
129 |
+ } |
|
130 |
+ } |
|
131 |
+#endif /* USE_TLS */ |
|
132 |
+#endif /* USE_TCP */ |
|
117 | 133 |
else{ |
118 | 134 |
LOG(L_CRIT, "BUG: msg_send: unknown proto %d\n", proto); |
119 | 135 |
goto error; |
... | ... |
@@ -67,6 +67,11 @@ extern struct socket_info* sendipv4_tcp; /* ipv4 socket to use when msg. |
67 | 67 |
extern struct socket_info* sendipv6_tcp; /* same as above for ipv6 */ |
68 | 68 |
extern int unix_tcp_sock; /* socket used for communication with tcp main*/ |
69 | 69 |
#endif |
70 |
+#ifdef USE_TLS |
|
71 |
+extern struct socket_info* sendipv4_tls; /* ipv4 socket to use when msg. |
|
72 |
+ comes from ipv6*/ |
|
73 |
+extern struct socket_info* sendipv6_tls; /* same as above for ipv6 */ |
|
74 |
+#endif |
|
70 | 75 |
|
71 | 76 |
extern unsigned int maxbuffer; |
72 | 77 |
extern int children_no; |
... | ... |
@@ -1164,7 +1164,11 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg, |
1164 | 1164 |
|
1165 | 1165 |
#ifdef USE_TCP |
1166 | 1166 |
/* add id if tcp */ |
1167 |
- if (msg->rcv.proto==PROTO_TCP){ |
|
1167 |
+ if (msg->rcv.proto==PROTO_TCP |
|
1168 |
+#ifdef USE_TLS |
|
1169 |
+ || msg->rcv.proto==PROTO_TLS |
|
1170 |
+#endif |
|
1171 |
+ ){ |
|
1168 | 1172 |
if ((id_buf=id_builder(msg, &id_len))==0){ |
1169 | 1173 |
LOG(L_ERR, "ERROR: build_req_buf_from_sip_req:" |
1170 | 1174 |
" id_builder failed\n"); |
... | ... |
@@ -1174,7 +1178,11 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg, |
1174 | 1178 |
extra_params.len=id_len; |
1175 | 1179 |
} |
1176 | 1180 |
/* if sending proto == tcp, check if Content-Length needs to be added*/ |
1177 |
- if (proto==PROTO_TCP){ |
|
1181 |
+ if (proto==PROTO_TCP |
|
1182 |
+#ifdef USE_TLS |
|
1183 |
+ || proto==PROTO_TLS |
|
1184 |
+#endif |
|
1185 |
+ ){ |
|
1178 | 1186 |
/* first of all parse content-length */ |
1179 | 1187 |
if (parse_headers(msg, HDR_CONTENTLENGTH, 0)==-1){ |
1180 | 1188 |
LOG(L_ERR, "build_req_buf_from_sip_req:" |
... | ... |
@@ -1390,7 +1398,11 @@ char * build_res_buf_from_sip_res( struct sip_msg* msg, |
1390 | 1398 |
#ifdef USE_TCP |
1391 | 1399 |
|
1392 | 1400 |
/* if sending proto == tcp, check if Content-Length needs to be added*/ |
1393 |
- if (msg->via2 && (msg->via2->proto==PROTO_TCP)){ |
|
1401 |
+ if (msg->via2 && ((msg->via2->proto==PROTO_TCP) |
|
1402 |
+#ifdef USE_TLS |
|
1403 |
+ || (msg->via2->proto==PROTO_TLS) |
|
1404 |
+#endif |
|
1405 |
+ )){ |
|
1394 | 1406 |
DBG("build_res_from_sip_res: checking content-length for \n%.*s\n", |
1395 | 1407 |
(int)msg->len, msg->buf); |
1396 | 1408 |
/* first of all parse content-length */ |
... | ... |
@@ -1872,6 +1884,8 @@ char* via_builder( unsigned int *len, |
1872 | 1884 |
/* dop nothing */ |
1873 | 1885 |
}else if (proto==PROTO_TCP){ |
1874 | 1886 |
memcpy(line_buf+MY_VIA_LEN-4, "TCP ", 4); |
1887 |
+ }else if (proto==PROTO_TLS){ |
|
1888 |
+ memcpy(line_buf+MY_VIA_LEN-4, "TLS", 4); |
|
1875 | 1889 |
}else{ |
1876 | 1890 |
LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", proto); |
1877 | 1891 |
return 0; |
... | ... |
@@ -368,7 +368,8 @@ void tcpconn_put(struct tcp_connection* c) |
368 | 368 |
|
369 | 369 |
|
370 | 370 |
/* finds a tcpconn & sends on it */ |
371 |
-int tcp_send(char* buf, unsigned len, union sockaddr_union* to, int id) |
|
371 |
+int tcp_send(int type, char* buf, unsigned len, union sockaddr_union* to, |
|
372 |
+ int id) |
|
372 | 373 |
{ |
373 | 374 |
struct tcp_connection *c; |
374 | 375 |
struct ip_addr ip; |
... | ... |
@@ -406,7 +407,7 @@ no_id: |
406 | 407 |
if (c==0){ |
407 | 408 |
DBG("tcp_send: no open tcp connection found, opening new one\n"); |
408 | 409 |
/* create tcp connection */ |
409 |
- if ((c=tcpconn_connect(to, PROTO_TCP))==0){ |
|
410 |
+ if ((c=tcpconn_connect(to, type))==0){ |
|
410 | 411 |
LOG(L_ERR, "ERROR: tcp_send: connect failed\n"); |
411 | 412 |
return -1; |
412 | 413 |
} |
... | ... |
@@ -457,7 +458,12 @@ get_fd: |
457 | 458 |
send_it: |
458 | 459 |
DBG("tcp_send: sending...\n"); |
459 | 460 |
lock_get(&c->write_lock); |
460 |
- n=send(fd, buf, len, |
|
461 |
+#ifdef USE_TLS |
|
462 |
+ if (c->type==PROTO_TLS) |
|
463 |
+ n=tls_blocking_write(c, fd, buf, len); |
|
464 |
+ else |
|
465 |
+#endif |
|
466 |
+ n=send(fd, buf, len, |
|
461 | 467 |
#ifdef HAVE_MSG_NOSIGNAL |
462 | 468 |
MSG_NOSIGNAL |
463 | 469 |
#else |
... | ... |
@@ -37,7 +37,8 @@ |
37 | 37 |
struct tcp_connection* tcpconn_get(int id, struct ip_addr* ip, int port, |
38 | 38 |
int timeout); |
39 | 39 |
void tcpconn_put(struct tcp_connection* c); |
40 |
-int tcp_send(char* buf, unsigned len, union sockaddr_union* to, int id); |
|
40 |
+int tcp_send(int type, char* buf, unsigned len, union sockaddr_union* to, |
|
41 |
+ int id); |
|
41 | 42 |
|
42 | 43 |
|
43 | 44 |
|