http-request set-src hdr(x-forwarded-for)
http-request set-src src,ipmask(24)
- When set-src is successful, the source port is set to 0.
+ When possible, set-src preserves the original source port as long as the
+ address family allows it, otherwise the source port is set to 0.
- set-src-port <expr> :
Is used to set the source port address to the value of specified
http-request set-src-port hdr(x-port)
http-request set-src-port int(4000)
- Be careful to use "set-src-port" after "set-src", because "set-src" sets
- the source port to 0.
+ When possible, set-src-port preserves the original source address as long
+ as the address family supports a port, otherwise it forces the source
+ address to IPv4 "0.0.0.0" before rewriting the port.
- set-dst <expr> :
Is used to set the destination IP address to the value of specified
http-request set-dst hdr(x-dst)
http-request set-dst dst,ipmask(24)
+ When possible, set-dst preserves the original destination port as long as
+ the address family allows it, otherwise the destination port is set to 0.
+
- set-dst-port <expr> :
Is used to set the destination port address to the value of specified
expression. If you want to connect to the new address/port, use
http-request set-dst-port hdr(x-port)
http-request set-dst-port int(4000)
+ When possible, set-dst-port preserves the original destination address as
+ long as the address family supports a port, otherwise it forces the
+ destination address to IPv4 "0.0.0.0" before rewriting the port.
+
- "silent-drop" : this stops the evaluation of the rules and makes the
client-facing connection suddenly disappear using a system-dependant way
that tries to prevent the client from being notified. The effect it then
}
/*
- * Execute the "set-src" action. May be called from {tcp,http}request
+ * Execute the "set-src" action. May be called from {tcp,http}request.
+ * It only changes the address and tries to preserve the original port. If the
+ * previous family was neither AF_INET nor AF_INET6, the port is set to zero.
*/
enum act_return tcp_action_req_set_src(struct act_rule *rule, struct proxy *px,
struct session *sess, struct stream *s, int flags)
smp = sample_fetch_as_type(px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->arg.expr, SMP_T_ADDR);
if (smp) {
+ int port = get_net_port(&cli_conn->addr.from);
+
if (smp->data.type == SMP_T_IPV4) {
((struct sockaddr_in *)&cli_conn->addr.from)->sin_family = AF_INET;
((struct sockaddr_in *)&cli_conn->addr.from)->sin_addr.s_addr = smp->data.u.ipv4.s_addr;
- ((struct sockaddr_in *)&cli_conn->addr.from)->sin_port = 0;
+ ((struct sockaddr_in *)&cli_conn->addr.from)->sin_port = port;
} else if (smp->data.type == SMP_T_IPV6) {
((struct sockaddr_in6 *)&cli_conn->addr.from)->sin6_family = AF_INET6;
memcpy(&((struct sockaddr_in6 *)&cli_conn->addr.from)->sin6_addr, &smp->data.u.ipv6, sizeof(struct in6_addr));
- ((struct sockaddr_in6 *)&cli_conn->addr.from)->sin6_port = 0;
+ ((struct sockaddr_in6 *)&cli_conn->addr.from)->sin6_port = port;
}
}
cli_conn->flags |= CO_FL_ADDR_FROM_SET;
}
/*
- * Execute the "set-dst" action. May be called from {tcp,http}request
+ * Execute the "set-dst" action. May be called from {tcp,http}request.
+ * It only changes the address and tries to preserve the original port. If the
+ * previous family was neither AF_INET nor AF_INET6, the port is set to zero.
*/
enum act_return tcp_action_req_set_dst(struct act_rule *rule, struct proxy *px,
struct session *sess, struct stream *s, int flags)
smp = sample_fetch_as_type(px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->arg.expr, SMP_T_ADDR);
if (smp) {
+ int port = get_net_port(&cli_conn->addr.to);
+
if (smp->data.type == SMP_T_IPV4) {
((struct sockaddr_in *)&cli_conn->addr.to)->sin_family = AF_INET;
((struct sockaddr_in *)&cli_conn->addr.to)->sin_addr.s_addr = smp->data.u.ipv4.s_addr;
} else if (smp->data.type == SMP_T_IPV6) {
((struct sockaddr_in6 *)&cli_conn->addr.to)->sin6_family = AF_INET6;
memcpy(&((struct sockaddr_in6 *)&cli_conn->addr.to)->sin6_addr, &smp->data.u.ipv6, sizeof(struct in6_addr));
- ((struct sockaddr_in6 *)&cli_conn->addr.to)->sin6_port = 0;
+ ((struct sockaddr_in6 *)&cli_conn->addr.to)->sin6_port = port;
}
cli_conn->flags |= CO_FL_ADDR_TO_SET;
}
}
/*
- * Execute the "set-src-port" action. May be called from {tcp,http}request
- * We must test the sin_family before setting the port
+ * Execute the "set-src-port" action. May be called from {tcp,http}request.
+ * We must test the sin_family before setting the port. If the address family
+ * is neither AF_INET nor AF_INET6, the address is forced to AF_INET "0.0.0.0"
+ * and the port is assigned.
*/
enum act_return tcp_action_req_set_src_port(struct act_rule *rule, struct proxy *px,
struct session *sess, struct stream *s, int flags)
smp = sample_fetch_as_type(px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->arg.expr, SMP_T_SINT);
if (smp) {
- if (((struct sockaddr_storage *)&cli_conn->addr.from)->ss_family == AF_INET) {
- ((struct sockaddr_in *)&cli_conn->addr.from)->sin_port = htons(smp->data.u.sint);
- } else if (((struct sockaddr_storage *)&cli_conn->addr.from)->ss_family == AF_INET6) {
+ if (cli_conn->addr.from.ss_family == AF_INET6) {
((struct sockaddr_in6 *)&cli_conn->addr.from)->sin6_port = htons(smp->data.u.sint);
+ } else {
+ if (cli_conn->addr.from.ss_family != AF_INET) {
+ cli_conn->addr.from.ss_family = AF_INET;
+ ((struct sockaddr_in *)&cli_conn->addr.from)->sin_addr.s_addr = 0;
+ }
+ ((struct sockaddr_in *)&cli_conn->addr.from)->sin_port = htons(smp->data.u.sint);
}
}
}
}
/*
- * Execute the "set-dst-port" action. May be called from {tcp,http}request
- * We must test the sin_family before setting the port
+ * Execute the "set-dst-port" action. May be called from {tcp,http}request.
+ * We must test the sin_family before setting the port. If the address family
+ * is neither AF_INET nor AF_INET6, the address is forced to AF_INET "0.0.0.0"
+ * and the port is assigned.
*/
enum act_return tcp_action_req_set_dst_port(struct act_rule *rule, struct proxy *px,
struct session *sess, struct stream *s, int flags)
smp = sample_fetch_as_type(px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->arg.expr, SMP_T_SINT);
if (smp) {
- if (((struct sockaddr_storage *)&cli_conn->addr.to)->ss_family == AF_INET) {
- ((struct sockaddr_in *)&cli_conn->addr.to)->sin_port = htons(smp->data.u.sint);
- } else if (((struct sockaddr_storage *)&cli_conn->addr.to)->ss_family == AF_INET6) {
- ((struct sockaddr_in6 *)&cli_conn->addr.to)->sin6_port = htons(smp->data.u.sint);
+ if (cli_conn->addr.from.ss_family == AF_INET6) {
+ ((struct sockaddr_in6 *)&cli_conn->addr.from)->sin6_port = htons(smp->data.u.sint);
+ } else {
+ if (cli_conn->addr.from.ss_family != AF_INET) {
+ cli_conn->addr.from.ss_family = AF_INET;
+ ((struct sockaddr_in *)&cli_conn->addr.from)->sin_addr.s_addr = 0;
+ }
+ ((struct sockaddr_in *)&cli_conn->addr.from)->sin_port = htons(smp->data.u.sint);
}
}
}