Browse Source

blacklist: ignore mask support

blacklist:
- a blacklist ignore mask (part of the send flags) is now
  supported by the blacklist functions
- blacklist add functions don't require anymore checking if the
  blacklist is enabled
- added dst_blacklist_force_add_to() and dst_blacklist_force_su_to()
tcp:
- updated to the changed dst_blacklist_su()
- a tcp connection send_flags and blacklist ignore mask are
  inherited from the packet that opens the connection
sctp:
- updated to the changed dst_blacklist_su()
Andrei Pelinescu-Onciul 15 years ago
parent
commit
5d6752dc5d
7 changed files with 192 additions and 130 deletions
  1. 6 6
      dst_blacklist.c
  2. 101 16
      dst_blacklist.h
  3. 2 3
      forward.c
  4. 6 9
      sctp_server.c
  5. 1 4
      tcp_conn.h
  6. 67 80
      tcp_main.c
  7. 9 12
      tcp_read.c

+ 6 - 6
dst_blacklist.c

@@ -794,8 +794,8 @@ inline static int dst_is_blacklisted_ip(unsigned char proto,
  * @param timeout - timeout in ticks
  * @return 0 on success, -1 on error
  */
-int dst_blacklist_add_to(unsigned char err_flags,  struct dest_info* si,
-						struct sip_msg* msg, ticks_t timeout)
+int dst_blacklist_force_add_to(unsigned char err_flags,  struct dest_info* si,
+								struct sip_msg* msg, ticks_t timeout)
 {
 	struct ip_addr ip;
 
@@ -812,12 +812,12 @@ int dst_blacklist_add_to(unsigned char err_flags,  struct dest_info* si,
 
 
 /** add dst to the blacklist, specifying the timeout.
- * (like @function dst_blacklist_add_to)= above, but uses 
+ * (like @function dst_blacklist_force_add_to)= above, but uses 
  * (proto, sockaddr_union) instead of struct dest_info)
  */
-int dst_blacklist_su_to(unsigned char err_flags, unsigned char proto,
-							union sockaddr_union* dst,
-							struct sip_msg* msg, ticks_t timeout)
+int dst_blacklist_force_su_to(unsigned char err_flags, unsigned char proto,
+								union sockaddr_union* dst,
+								struct sip_msg* msg, ticks_t timeout)
 {
 	struct ip_addr ip;
 #ifdef DST_BLACKLIST_HOOKS

+ 101 - 16
dst_blacklist.h

@@ -30,6 +30,8 @@
  * --------
  *  2006-07-29  created by andrei
  *  2007-07-30  dst blacklist measurements added (Gergo)
+ *  2009-12-22  blacklist ignore mask support and dst_blacklist_{add,su}
+ *               switched to macros (andrei)
  */
 
 #ifndef dst_black_list_h
@@ -85,27 +87,110 @@ int init_dst_blacklist_stats(int iproc_num);
 void destroy_dst_blacklist();
 
 
-/* like dst_blacklist_add, but the timeout can be also set */
-int dst_blacklist_add_to(unsigned char err_flags, struct dest_info* si,
-						struct sip_msg* msg, ticks_t timeout);
-/* like above, but using a differnt way of passing the target */
-int dst_blacklist_su_to(unsigned char err_flags, unsigned char proto,
-							union sockaddr_union* dst,
-							struct sip_msg* msg, ticks_t timeout);
+/** force add to the blacklist.
+ * like @function dst_blacklist_add_to, but no ignore mask or
+ * blacklist enabled checks are made.
+ * @see dst_blacklist_add_to for the parameters and return value.
+ */
+int dst_blacklist_force_add_to(unsigned char err_flags, struct dest_info* si,
+								struct sip_msg* msg, ticks_t timeout);
 
-/** adds a dst to the blacklist with default timeout.
- * @see dst_blacklist_add_to for more details.
+/** force add to the blacklist, long version.
+ * like @function dst_blacklist_su_to, but no ignore mask or
+ * blacklist enabled checks are made.
+ * @see dst_blacklist_su_to for the parameters and return value.
  */
-#define dst_blacklist_add(err_flags, si, msg) \
-	dst_blacklist_add_to((err_flags), (si), (msg), \
-		S_TO_TICKS(cfg_get(core, core_cfg, blst_timeout)))
+int dst_blacklist_force_su_to(	unsigned char err_flags,
+								unsigned char proto,
+								union sockaddr_union* dst,
+								struct sip_msg* msg,
+								ticks_t timeout);
+
+
+/** checks if blacklist should be used.
+  * @param  err_flags - blacklist reason
+  * @param si - filled dst_info structure pointer.
+  * @return 1 if blacklist is enabled (core_cfg) and the event/error
+  *           is not in the ignore list.
+  *         0 otherwise
+  */
+#define should_blacklist(err_flags, si) \
+	(cfg_get(core, core_cfg, use_dst_blacklist) && \
+		((err_flags) & (si)->send_flags.blst_imask))
+
+
+/** checks if blacklist should be used, long version.
+  * @param  err_flags - blacklist reason
+  * @param snd_flags - snd_flags pointer, can be 0.
+  * @param proto - protocol, can be 0 (PROTO_NONE).
+  * @param si  - sockaddr_union pointer, can be 0.
+  * @return 1 if blacklist is enabled (core_cfg) and the event/error
+  *           is not in the ignore list.
+  *         0 otherwise
+  */
+#define should_blacklist_su(err_flags, snd_flags, proto, su) \
+	(cfg_get(core, core_cfg, use_dst_blacklist) && \
+		((err_flags) & \
+		 			~((snd_flags)?((snd_flags_t*)(snd_flags))->blst_imask:0)))
+
+
+/** adds a dst to the blacklist.
+ *
+ * @param  err_flags - blacklist reason
+ * @param si  - dest_info structure (dst).
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
+ * @param timeout - timeout in ticks.
+ * @return >=0 on success, -1 on error.
+ */
+#define dst_blacklist_add_to(err_flags, si, msg, timeout) \
+	(should_blacklist(err_flags, si)? \
+		dst_blacklist_force_add_to((err_flags), (si), (msg), (timeout))\
+		: 0)
+
+
+/** adds a dst to the blacklist, long version.
+ * Similar to dst_blacklist_add_to, but uses "unpacked" parameters.
+ * @param  err_flags - blacklist reason
+ * @param proto - protocol.
+ * @param dst  - sockaddr_union pointer.
+ * @param snd_flags - snd_flags pointer, can be 0.
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
+ * @param timeout - timeout in ticks.
+ * @return >=0 on success, -1 on error.
+ */
+#define dst_blacklist_su_to(err_flags, proto, dst, snd_flags, msg, timeout) \
+	(should_blacklist_su(err_flags, snd_flags, proto, dst) ? \
+		dst_blacklist_force_su_to((err_flags), (proto), (dst), (msg), \
+									(timeout))\
+		: 0)
+
 
 /** adds a dst to the blacklist with default timeout.
- * @see dst_blacklist_su_to for more details.
+ *
+ * @param  err_flags - blacklist reason
+ * @param si  - dest_info structure (dst).
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
+ * @return >=0 on success, -1 on error.
+ * @see dst_blacklist_add_to.
+ */
+#define dst_blacklist_add(err_flags, si, msg) \
+	dst_blacklist_add_to(err_flags, si, msg, \
+							S_TO_TICKS(cfg_get(core, core_cfg, blst_timeout)))
+
+
+/** adds a dst to the blacklist with default timeout, long version.
+ * Similar to dst_blacklist_add_to, but uses "unpacked" parameters.
+ * @param  err_flags - blacklist reason
+ * @param proto - protocol.
+ * @param dst  - sockaddr_union pointer.
+ * @param snd_flags - snd_flags pointer, can be 0.
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
+ * @return >=0 on success, -1 on error.
+ * @see dst_blacklist_su_to.
  */
-#define dst_blacklist_su(err_flags, proto, dst, msg) \
-	dst_blacklist_su_to((err_flags), (proto), (dst), (msg), \
-		S_TO_TICKS(cfg_get(core, core_cfg, blst_timeout)))
+#define dst_blacklist_su(err_flags, proto, dst, snd_flags, msg) \
+	dst_blacklist_su_to(err_flags, proto, dst, snd_flags, msg, \
+							S_TO_TICKS(cfg_get(core, core_cfg, blst_timeout)))
 
 int dst_is_blacklisted(struct dest_info* si, struct sip_msg* msg);
 /* delete an entry from the blacklist */

+ 2 - 3
forward.c

@@ -541,8 +541,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
 		if (msg_send(send_info, buf, len)<0){
 			ret=ser_error=E_SEND;
 #ifdef USE_DST_BLACKLIST
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
-				dst_blacklist_add(BLST_ERR_SEND, send_info, msg);
+			dst_blacklist_add(BLST_ERR_SEND, send_info, msg);
 #endif
 #ifdef USE_DNS_FAILOVER
 			continue; /* try another ip */
@@ -698,7 +697,7 @@ int forward_reply(struct sip_msg* msg)
 	}
 
 	dst.proto=msg->via2->proto;
-	dst.send_flags.f=msg->fwd_send_flags.f | msg->rpl_send_flags.f;
+	SND_FLAGS_OR(&dst.send_flags, &msg->fwd_send_flags, &msg->rpl_send_flags);
 	if (update_sock_struct_from_via( &dst.to, msg, msg->via2 )==-1) goto error;
 #ifdef USE_COMP
 	dst.comp=msg->via2->comp_no;

+ 6 - 9
sctp_server.c

@@ -2126,13 +2126,12 @@ static int sctp_handle_send_failed(struct socket_info* si,
 		ret=sctp_msg_send_ext(&dst, data, data_len, &sinfo);
 	}
 #ifdef USE_DST_BLACKLIST
-	 else if (cfg_get(core, core_cfg, use_dst_blacklist) &&
-					cfg_get(sctp, sctp_cfg, send_retries)) {
+	 else if (cfg_get(sctp, sctp_cfg, send_retries)) {
 		/* blacklist only if send_retries is on, if off we blacklist
 		   from SCTP_ASSOC_CHANGE: SCTP_COMM_LOST/SCTP_CANT_STR_ASSOC
 		   which is better (because we can tell connect errors from send
 		   errors and we blacklist a failed dst only once) */
-		dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0);
+		dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0, 0);
 	}
 #endif /* USE_DST_BLACKLIST */
 	
@@ -2213,9 +2212,8 @@ again:
 #ifdef USE_DST_BLACKLIST
 			/* blacklist only if send_retries is turned off (if on we don't
 			   know here if we did retry or we are at the first error) */
-			if (cfg_get(core, core_cfg, use_dst_blacklist) &&
-					(cfg_get(sctp, sctp_cfg, send_retries)==0))
-						dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0);
+			if (cfg_get(sctp, sctp_cfg, send_retries)==0)
+						dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0, 0);
 #endif /* USE_DST_BLACKLIST */
 			/* no break */
 		case SCTP_SHUTDOWN_COMP:
@@ -2243,9 +2241,8 @@ again:
 #ifdef USE_DST_BLACKLIST
 			/* blacklist only if send_retries is turned off (if on we don't 
 			   know here if we did retry or we are at the first error) */
-			if (cfg_get(core, core_cfg, use_dst_blacklist) &&
-					(cfg_get(sctp, sctp_cfg, send_retries)==0))
-						dst_blacklist_su(BLST_ERR_CONNECT, PROTO_SCTP, su, 0);
+			if (cfg_get(sctp, sctp_cfg, send_retries)==0)
+					dst_blacklist_su(BLST_ERR_CONNECT, PROTO_SCTP, su, 0, 0);
 #endif /* USE_DST_BLACKLIST */
 			break;
 		default:

+ 1 - 4
tcp_conn.h

@@ -193,10 +193,7 @@ struct tcp_connection{
 /* helper macros */
 
 #define tcpconn_set_send_flags(c, snd_flags) \
-	do{ \
-		(c)->send_flags.f|=(snd_flags).f; \
-		(c)->send_flags.blst_imask|=(snd_flags).blst_imask; \
-	}while(0)
+	SND_FLAGS_OR(&(c)->send_flags, &(c)->send_flags, &(snd_flags))
 
 #define tcpconn_close_after_send(c)	((c)->send_flags.f & SND_F_CON_CLOSE)
 

+ 67 - 80
tcp_main.c

@@ -477,7 +477,7 @@ error:
  * if BLOCKING_USE_SELECT and HAVE_SELECT are defined it will internally
  * use select() instead of poll (bad if fd > FD_SET_SIZE, poll is preferred)
  */
-static int tcp_blocking_connect(int fd, int type,
+static int tcp_blocking_connect(int fd, int type, snd_flags_t* send_flags,
 								const struct sockaddr *servaddr,
 								socklen_t addrlen)
 {
@@ -570,18 +570,16 @@ error_errno:
 		case ENETUNREACH:
 		case EHOSTUNREACH:
 #ifdef USE_DST_BLACKLIST
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
-				dst_blacklist_su(BLST_ERR_CONNECT, type,
-							 (union sockaddr_union*)servaddr, 0);
+			dst_blacklist_su(BLST_ERR_CONNECT, type,
+							 (union sockaddr_union*)servaddr, send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 			TCP_EV_CONNECT_UNREACHABLE(errno, 0, 0,
 							(union sockaddr_union*)servaddr, type);
 			break;
 		case ETIMEDOUT:
 #ifdef USE_DST_BLACKLIST
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
-				dst_blacklist_su(BLST_ERR_CONNECT, type,
-								 (union sockaddr_union*)servaddr, 0);
+			dst_blacklist_su(BLST_ERR_CONNECT, type,
+							 (union sockaddr_union*)servaddr, send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 			TCP_EV_CONNECT_TIMEOUT(errno, 0, 0,
 							(union sockaddr_union*)servaddr, type);
@@ -589,9 +587,8 @@ error_errno:
 		case ECONNREFUSED:
 		case ECONNRESET:
 #ifdef USE_DST_BLACKLIST
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
-				dst_blacklist_su(BLST_ERR_CONNECT, type,
-								 (union sockaddr_union*)servaddr, 0);
+			dst_blacklist_su(BLST_ERR_CONNECT, type,
+							 (union sockaddr_union*)servaddr, send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 			TCP_EV_CONNECT_RST(errno, 0, 0,
 							(union sockaddr_union*)servaddr, type);
@@ -611,9 +608,8 @@ error_errno:
 error_timeout:
 	/* timeout */
 #ifdef USE_DST_BLACKLIST
-	if (cfg_get(core, core_cfg, use_dst_blacklist))
-		dst_blacklist_su(BLST_ERR_CONNECT, type,
-							(union sockaddr_union*)servaddr, 0);
+	dst_blacklist_su(BLST_ERR_CONNECT, type,
+						(union sockaddr_union*)servaddr, send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 	TCP_EV_CONNECT_TIMEOUT(0, 0, 0, (union sockaddr_union*)servaddr, type);
 	LOG(L_ERR, "ERROR: tcp_blocking_connect %s: timeout %d s elapsed "
@@ -666,22 +662,16 @@ inline static int _wbufq_add(struct  tcp_connection* c, char* data,
 		if (q->first && TICKS_LT(q->wr_timeout, t)){
 			if (unlikely(c->state==S_CONN_CONNECT)){
 #ifdef USE_DST_BLACKLIST
-				if (likely(cfg_get(core, core_cfg, use_dst_blacklist))){
-					DBG("blacklisting, state=%d\n", c->state);
-					dst_blacklist_su( BLST_ERR_CONNECT, c->rcv.proto,
-										&c->rcv.src_su, 0);
-				}
+				dst_blacklist_su( BLST_ERR_CONNECT, c->rcv.proto,
+										&c->rcv.src_su, &c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 				TCP_EV_CONNECT_TIMEOUT(0, TCP_LADDR(c), TCP_LPORT(c),
 											TCP_PSU(c), TCP_PROTO(c));
 				TCP_STATS_CONNECT_FAILED();
 			}else{
 #ifdef USE_DST_BLACKLIST
-				if (likely(cfg_get(core, core_cfg, use_dst_blacklist))){
-					DBG("blacklisting, state=%d\n", c->state);
-					dst_blacklist_su( BLST_ERR_SEND, c->rcv.proto,
-										&c->rcv.src_su, 0);
-				}
+				dst_blacklist_su( BLST_ERR_SEND, c->rcv.proto,
+									&c->rcv.src_su, &c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 				TCP_EV_SEND_TIMEOUT(0, &c->rcv);
 				TCP_STATS_SEND_TIMEOUT();
@@ -865,10 +855,10 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
 							case ENETUNREACH:
 							case EHOSTUNREACH: /* not posix for send() */
 #ifdef USE_DST_BLACKLIST
-								if (cfg_get(core, core_cfg, use_dst_blacklist))
-									dst_blacklist_su(BLST_ERR_CONNECT,
-															c->rcv.proto,
-															&c->rcv.src_su, 0);
+								dst_blacklist_su(BLST_ERR_CONNECT,
+													c->rcv.proto,
+													&c->rcv.src_su,
+													&c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 								TCP_EV_CONNECT_UNREACHABLE(errno, TCP_LADDR(c),
 													TCP_LPORT(c), TCP_PSU(c),
@@ -877,10 +867,10 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
 							case ECONNREFUSED:
 							case ECONNRESET:
 #ifdef USE_DST_BLACKLIST
-								if (cfg_get(core, core_cfg, use_dst_blacklist))
-									dst_blacklist_su(BLST_ERR_CONNECT,
-															c->rcv.proto,
-															&c->rcv.src_su, 0);
+								dst_blacklist_su(BLST_ERR_CONNECT,
+													c->rcv.proto,
+													&c->rcv.src_su,
+													&c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 								TCP_EV_CONNECT_RST(0, TCP_LADDR(c),
 													TCP_LPORT(c), TCP_PSU(c),
@@ -901,10 +891,10 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
 							case ENETUNREACH:
 							case EHOSTUNREACH: /* not posix for send() */
 #ifdef USE_DST_BLACKLIST
-								if (cfg_get(core, core_cfg, use_dst_blacklist))
-									dst_blacklist_su(BLST_ERR_SEND,
-														c->rcv.proto,
-														&c->rcv.src_su, 0);
+								dst_blacklist_su(BLST_ERR_SEND,
+													c->rcv.proto,
+													&c->rcv.src_su,
+													&c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 								break;
 						}
@@ -1083,6 +1073,7 @@ error:
 inline static int tcp_do_connect(	union sockaddr_union* server,
 									union sockaddr_union* from,
 									int type,
+									snd_flags_t* send_flags,
 									union sockaddr_union* res_local_addr,
 									struct socket_info** res_si,
 									enum tcp_conn_states *state
@@ -1127,23 +1118,23 @@ again:
 					case ENETUNREACH:
 					case EHOSTUNREACH:
 #ifdef USE_DST_BLACKLIST
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
-							dst_blacklist_su(BLST_ERR_CONNECT, type, server,0);
+						dst_blacklist_su(BLST_ERR_CONNECT, type, server,
+											send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 						TCP_EV_CONNECT_UNREACHABLE(errno, 0, 0, server, type);
 						break;
 					case ETIMEDOUT:
 #ifdef USE_DST_BLACKLIST
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
-							dst_blacklist_su(BLST_ERR_CONNECT, type, server,0);
+						dst_blacklist_su(BLST_ERR_CONNECT, type, server,
+											send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 						TCP_EV_CONNECT_TIMEOUT(errno, 0, 0, server, type);
 						break;
 					case ECONNREFUSED:
 					case ECONNRESET:
 #ifdef USE_DST_BLACKLIST
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
-							dst_blacklist_su(BLST_ERR_CONNECT, type, server,0);
+						dst_blacklist_su(BLST_ERR_CONNECT, type, server,
+											send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 						TCP_EV_CONNECT_RST(errno, 0, 0, server, type);
 						break;
@@ -1162,7 +1153,7 @@ again:
 		}
 	}else{
 #endif /* TCP_ASYNC */
-		if (tcp_blocking_connect(s, type, &server->s,
+		if (tcp_blocking_connect(s, type,  send_flags, &server->s,
 									sockaddru_len(*server))<0){
 			LOG(L_ERR, "ERROR: tcp_do_connect: tcp_blocking_connect %s"
 						" failed\n", su2a(server, sizeof(*server)));
@@ -1212,9 +1203,9 @@ error:
 
 
 
-struct tcp_connection* tcpconn_connect( union sockaddr_union* server, 
+struct tcp_connection* tcpconn_connect( union sockaddr_union* server,
 										union sockaddr_union* from,
-										int type)
+										int type, snd_flags_t* send_flags)
 {
 	int s;
 	struct socket_info* si;
@@ -1231,7 +1222,7 @@ struct tcp_connection* tcpconn_connect( union sockaddr_union* server,
 					cfg_get(tcp, tcp_cfg, max_connections));
 		goto error;
 	}
-	s=tcp_do_connect(server, from, type, &my_name, &si, &state);
+	s=tcp_do_connect(server, from, type,  send_flags, &my_name, &si, &state);
 	if (s==-1){
 		LOG(L_ERR, "ERROR: tcp_do_connect %s: failed (%d) %s\n",
 				su2a(server, sizeof(*server)), errno, strerror(errno));
@@ -1243,6 +1234,7 @@ struct tcp_connection* tcpconn_connect( union sockaddr_union* server,
 				 " socket\n", su2a(server, sizeof(*server)));
 		goto error;
 	}
+	tcpconn_set_send_flags(con, *send_flags);
 	return con;
 	/*FIXME: set sock idx! */
 error:
@@ -1264,7 +1256,8 @@ int tcpconn_finish_connect( struct tcp_connection* c,
 	struct tcp_conn_alias* a;
 	int new_conn_alias_flags;
 	
-	s=tcp_do_connect(&c->rcv.src_su, from, c->type, &local_addr, &si, &state);
+	s=tcp_do_connect(&c->rcv.src_su, from, c->type, &c->send_flags,
+						&local_addr, &si, &state);
 	if (unlikely(s==-1)){
 		LOG(L_ERR, "ERROR: tcpconn_finish_connect %s: tcp_do_connect for %p"
 					" failed\n", su2a(&c->rcv.src_su, sizeof(c->rcv.src_su)),
@@ -1898,8 +1891,7 @@ int tcp_send(struct dest_info* dst, union sockaddr_union* from,
 						case ENETUNREACH:
 						case EHOSTUNREACH:  /* not posix for send() */
 #ifdef USE_DST_BLACKLIST
-							if (cfg_get(core, core_cfg, use_dst_blacklist))
-								dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
+							dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
 #endif /* USE_DST_BLACKLIST */
 							TCP_EV_CONNECT_UNREACHABLE(errno, TCP_LADDR(c),
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
@@ -1907,8 +1899,7 @@ int tcp_send(struct dest_info* dst, union sockaddr_union* from,
 						case ECONNREFUSED:
 						case ECONNRESET:
 #ifdef USE_DST_BLACKLIST
-							if (cfg_get(core, core_cfg, use_dst_blacklist))
-								dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
+							dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
 #endif /* USE_DST_BLACKLIST */
 							TCP_EV_CONNECT_RST(errno, TCP_LADDR(c),
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
@@ -1950,7 +1941,8 @@ int tcp_send(struct dest_info* dst, union sockaddr_union* from,
 				goto end;
 			}
 #endif /* TCP_CONNECT_WAIT  && TCP_ASYNC */
-			if (unlikely((c=tcpconn_connect(&dst->to, from, dst->proto))==0)){
+			if (unlikely((c=tcpconn_connect(&dst->to, from, dst->proto,
+											&dst->send_flags))==0)){
 				LOG(L_ERR, "ERROR: tcp_send %s: connect failed\n",
 								su2a(&dst->to, sizeof(dst->to)));
 				return -1;
@@ -2143,9 +2135,8 @@ send_it:
 				case ENETUNREACH:
 				case EHOSTUNREACH: /* not posix for send() */
 #ifdef USE_DST_BLACKLIST
-					if (cfg_get(core, core_cfg, use_dst_blacklist))
-						dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
-											&c->rcv.src_su, 0);
+					dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
+										&c->rcv.src_su, &c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 					TCP_EV_CONNECT_UNREACHABLE(errno, TCP_LADDR(c),
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
@@ -2153,9 +2144,8 @@ send_it:
 				case ECONNREFUSED:
 				case ECONNRESET:
 #ifdef USE_DST_BLACKLIST
-					if (cfg_get(core, core_cfg, use_dst_blacklist))
-						dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
-											&c->rcv.src_su, 0);
+					dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
+										&c->rcv.src_su, &c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 					TCP_EV_CONNECT_RST(errno, TCP_LADDR(c), TCP_LPORT(c),
 										TCP_PSU(c), TCP_PROTO(c));
@@ -2174,9 +2164,8 @@ send_it:
 				case ENETUNREACH:
 				/*case EHOSTUNREACH: -- not posix */
 #ifdef USE_DST_BLACKLIST
-					if (cfg_get(core, core_cfg, use_dst_blacklist))
-						dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
-												&c->rcv.src_su, 0);
+					dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
+										&c->rcv.src_su, &c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 					break;
 			}
@@ -2896,10 +2885,10 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
 					/* timeout */
 					if (unlikely(tcpconn->state==S_CONN_CONNECT)){
 #ifdef USE_DST_BLACKLIST
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
-							dst_blacklist_su( BLST_ERR_CONNECT,
-													tcpconn->rcv.proto,
-													&tcpconn->rcv.src_su, 0);
+						dst_blacklist_su( BLST_ERR_CONNECT,
+											tcpconn->rcv.proto,
+											&tcpconn->rcv.src_su,
+											&tcpconn->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 						TCP_EV_CONNECT_TIMEOUT(0, TCP_LADDR(tcpconn),
 										TCP_LPORT(tcpconn), TCP_PSU(tcpconn),
@@ -2907,10 +2896,10 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
 						TCP_STATS_CONNECT_FAILED();
 					}else{
 #ifdef USE_DST_BLACKLIST
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
-							dst_blacklist_su( BLST_ERR_SEND,
-													tcpconn->rcv.proto,
-													&tcpconn->rcv.src_su, 0);
+						dst_blacklist_su( BLST_ERR_SEND,
+											tcpconn->rcv.proto,
+											&tcpconn->rcv.src_su,
+											&tcpconn->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 						TCP_EV_SEND_TIMEOUT(0, &tcpconn->rcv);
 						TCP_STATS_SEND_TIMEOUT();
@@ -3553,9 +3542,9 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, short ev,
 			if (unlikely(ev & POLLERR)){
 				if (unlikely(tcpconn->state==S_CONN_CONNECT)){
 #ifdef USE_DST_BLACKLIST
-					if (cfg_get(core, core_cfg, use_dst_blacklist))
-						dst_blacklist_su(BLST_ERR_CONNECT, tcpconn->rcv.proto,
-											&tcpconn->rcv.src_su, 0);
+					dst_blacklist_su(BLST_ERR_CONNECT, tcpconn->rcv.proto,
+										&tcpconn->rcv.src_su,
+										&tcpconn->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 					TCP_EV_CONNECT_ERR(0, TCP_LADDR(tcpconn),
 										TCP_LPORT(tcpconn), TCP_PSU(tcpconn),
@@ -3563,9 +3552,9 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, short ev,
 					TCP_STATS_CONNECT_FAILED();
 				}else{
 #ifdef USE_DST_BLACKLIST
-					if (cfg_get(core, core_cfg, use_dst_blacklist))
-						dst_blacklist_su(BLST_ERR_SEND, tcpconn->rcv.proto,
-											&tcpconn->rcv.src_su, 0);
+					dst_blacklist_su(BLST_ERR_SEND, tcpconn->rcv.proto,
+										&tcpconn->rcv.src_su,
+										&tcpconn->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 					TCP_STATS_CON_RESET(); /* FIXME: it could != RST */
 				}
@@ -3740,18 +3729,16 @@ static ticks_t tcpconn_main_timeout(ticks_t t, struct timer_ln* tl, void* data)
 	if (tcp_async && _wbufq_non_empty(c) && TICKS_GE(t, c->wbuf_q.wr_timeout)){
 		if (unlikely(c->state==S_CONN_CONNECT)){
 #ifdef USE_DST_BLACKLIST
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
-				dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
-									&c->rcv.src_su, 0);
+			dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto, &c->rcv.src_su,
+								&c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 			TCP_EV_CONNECT_TIMEOUT(0, TCP_LADDR(c), TCP_LPORT(c), TCP_PSU(c),
 									TCP_PROTO(c));
 			TCP_STATS_CONNECT_FAILED();
 		}else{
 #ifdef USE_DST_BLACKLIST
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
-				dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
-									&c->rcv.src_su, 0);
+			dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto, &c->rcv.src_su,
+								&c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 			TCP_EV_SEND_TIMEOUT(0, &c->rcv);
 			TCP_STATS_SEND_TIMEOUT();

+ 9 - 12
tcp_read.c

@@ -153,20 +153,18 @@ again:
 					switch(errno){
 						case ECONNRESET:
 #ifdef USE_DST_BLACKLIST
-							if (cfg_get(core, core_cfg, use_dst_blacklist))
-								dst_blacklist_su(BLST_ERR_CONNECT,
-														c->rcv.proto,
-														&c->rcv.src_su, 0);
+							dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
+												&c->rcv.src_su,
+												&c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 							TCP_EV_CONNECT_RST(errno, TCP_LADDR(c),
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
 							break;
 						case ETIMEDOUT:
 #ifdef USE_DST_BLACKLIST
-							if (cfg_get(core, core_cfg, use_dst_blacklist))
-								dst_blacklist_su(BLST_ERR_CONNECT,
-														c->rcv.proto,
-														&c->rcv.src_su, 0);
+							dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
+												&c->rcv.src_su,
+												&c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 							TCP_EV_CONNECT_TIMEOUT(errno, TCP_LADDR(c),
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
@@ -182,10 +180,9 @@ again:
 								TCP_STATS_CON_RESET();
 							case ETIMEDOUT:
 #ifdef USE_DST_BLACKLIST
-								if (cfg_get(core, core_cfg, use_dst_blacklist))
-									dst_blacklist_su(BLST_ERR_SEND,
-														c->rcv.proto,
-														&c->rcv.src_su, 0);
+								dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
+													&c->rcv.src_su,
+													&c->send_flags, 0);
 #endif /* USE_DST_BLACKLIST */
 								break;
 						}