Browse code

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 authored on 23/12/2009 08:44:12
Showing 7 changed files
... ...
@@ -794,8 +794,8 @@ inline static int dst_is_blacklisted_ip(unsigned char proto,
794 794
  * @param timeout - timeout in ticks
795 795
  * @return 0 on success, -1 on error
796 796
  */
797
-int dst_blacklist_add_to(unsigned char err_flags,  struct dest_info* si,
798
-						struct sip_msg* msg, ticks_t timeout)
797
+int dst_blacklist_force_add_to(unsigned char err_flags,  struct dest_info* si,
798
+								struct sip_msg* msg, ticks_t timeout)
799 799
 {
800 800
 	struct ip_addr ip;
801 801
 
... ...
@@ -812,12 +812,12 @@ int dst_blacklist_add_to(unsigned char err_flags,  struct dest_info* si,
812 812
 
813 813
 
814 814
 /** add dst to the blacklist, specifying the timeout.
815
- * (like @function dst_blacklist_add_to)= above, but uses 
815
+ * (like @function dst_blacklist_force_add_to)= above, but uses 
816 816
  * (proto, sockaddr_union) instead of struct dest_info)
817 817
  */
818
-int dst_blacklist_su_to(unsigned char err_flags, unsigned char proto,
819
-							union sockaddr_union* dst,
820
-							struct sip_msg* msg, ticks_t timeout)
818
+int dst_blacklist_force_su_to(unsigned char err_flags, unsigned char proto,
819
+								union sockaddr_union* dst,
820
+								struct sip_msg* msg, ticks_t timeout)
821 821
 {
822 822
 	struct ip_addr ip;
823 823
 #ifdef DST_BLACKLIST_HOOKS
... ...
@@ -30,6 +30,8 @@
30 30
  * --------
31 31
  *  2006-07-29  created by andrei
32 32
  *  2007-07-30  dst blacklist measurements added (Gergo)
33
+ *  2009-12-22  blacklist ignore mask support and dst_blacklist_{add,su}
34
+ *               switched to macros (andrei)
33 35
  */
34 36
 
35 37
 #ifndef dst_black_list_h
... ...
@@ -85,27 +87,110 @@ int init_dst_blacklist_stats(int iproc_num);
85 85
 void destroy_dst_blacklist();
86 86
 
87 87
 
88
-/* like dst_blacklist_add, but the timeout can be also set */
89
-int dst_blacklist_add_to(unsigned char err_flags, struct dest_info* si,
90
-						struct sip_msg* msg, ticks_t timeout);
91
-/* like above, but using a differnt way of passing the target */
92
-int dst_blacklist_su_to(unsigned char err_flags, unsigned char proto,
93
-							union sockaddr_union* dst,
94
-							struct sip_msg* msg, ticks_t timeout);
88
+/** force add to the blacklist.
89
+ * like @function dst_blacklist_add_to, but no ignore mask or
90
+ * blacklist enabled checks are made.
91
+ * @see dst_blacklist_add_to for the parameters and return value.
92
+ */
93
+int dst_blacklist_force_add_to(unsigned char err_flags, struct dest_info* si,
94
+								struct sip_msg* msg, ticks_t timeout);
95 95
 
96
-/** adds a dst to the blacklist with default timeout.
97
- * @see dst_blacklist_add_to for more details.
96
+/** force add to the blacklist, long version.
97
+ * like @function dst_blacklist_su_to, but no ignore mask or
98
+ * blacklist enabled checks are made.
99
+ * @see dst_blacklist_su_to for the parameters and return value.
98 100
  */
99
-#define dst_blacklist_add(err_flags, si, msg) \
100
-	dst_blacklist_add_to((err_flags), (si), (msg), \
101
-		S_TO_TICKS(cfg_get(core, core_cfg, blst_timeout)))
101
+int dst_blacklist_force_su_to(	unsigned char err_flags,
102
+								unsigned char proto,
103
+								union sockaddr_union* dst,
104
+								struct sip_msg* msg,
105
+								ticks_t timeout);
106
+
107
+
108
+/** checks if blacklist should be used.
109
+  * @param  err_flags - blacklist reason
110
+  * @param si - filled dst_info structure pointer.
111
+  * @return 1 if blacklist is enabled (core_cfg) and the event/error
112
+  *           is not in the ignore list.
113
+  *         0 otherwise
114
+  */
115
+#define should_blacklist(err_flags, si) \
116
+	(cfg_get(core, core_cfg, use_dst_blacklist) && \
117
+		((err_flags) & (si)->send_flags.blst_imask))
118
+
119
+
120
+/** checks if blacklist should be used, long version.
121
+  * @param  err_flags - blacklist reason
122
+  * @param snd_flags - snd_flags pointer, can be 0.
123
+  * @param proto - protocol, can be 0 (PROTO_NONE).
124
+  * @param si  - sockaddr_union pointer, can be 0.
125
+  * @return 1 if blacklist is enabled (core_cfg) and the event/error
126
+  *           is not in the ignore list.
127
+  *         0 otherwise
128
+  */
129
+#define should_blacklist_su(err_flags, snd_flags, proto, su) \
130
+	(cfg_get(core, core_cfg, use_dst_blacklist) && \
131
+		((err_flags) & \
132
+		 			~((snd_flags)?((snd_flags_t*)(snd_flags))->blst_imask:0)))
133
+
134
+
135
+/** adds a dst to the blacklist.
136
+ *
137
+ * @param  err_flags - blacklist reason
138
+ * @param si  - dest_info structure (dst).
139
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
140
+ * @param timeout - timeout in ticks.
141
+ * @return >=0 on success, -1 on error.
142
+ */
143
+#define dst_blacklist_add_to(err_flags, si, msg, timeout) \
144
+	(should_blacklist(err_flags, si)? \
145
+		dst_blacklist_force_add_to((err_flags), (si), (msg), (timeout))\
146
+		: 0)
147
+
148
+
149
+/** adds a dst to the blacklist, long version.
150
+ * Similar to dst_blacklist_add_to, but uses "unpacked" parameters.
151
+ * @param  err_flags - blacklist reason
152
+ * @param proto - protocol.
153
+ * @param dst  - sockaddr_union pointer.
154
+ * @param snd_flags - snd_flags pointer, can be 0.
155
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
156
+ * @param timeout - timeout in ticks.
157
+ * @return >=0 on success, -1 on error.
158
+ */
159
+#define dst_blacklist_su_to(err_flags, proto, dst, snd_flags, msg, timeout) \
160
+	(should_blacklist_su(err_flags, snd_flags, proto, dst) ? \
161
+		dst_blacklist_force_su_to((err_flags), (proto), (dst), (msg), \
162
+									(timeout))\
163
+		: 0)
164
+
102 165
 
103 166
 /** adds a dst to the blacklist with default timeout.
104
- * @see dst_blacklist_su_to for more details.
167
+ *
168
+ * @param  err_flags - blacklist reason
169
+ * @param si  - dest_info structure (dst).
170
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
171
+ * @return >=0 on success, -1 on error.
172
+ * @see dst_blacklist_add_to.
173
+ */
174
+#define dst_blacklist_add(err_flags, si, msg) \
175
+	dst_blacklist_add_to(err_flags, si, msg, \
176
+							S_TO_TICKS(cfg_get(core, core_cfg, blst_timeout)))
177
+
178
+
179
+/** adds a dst to the blacklist with default timeout, long version.
180
+ * Similar to dst_blacklist_add_to, but uses "unpacked" parameters.
181
+ * @param  err_flags - blacklist reason
182
+ * @param proto - protocol.
183
+ * @param dst  - sockaddr_union pointer.
184
+ * @param snd_flags - snd_flags pointer, can be 0.
185
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
186
+ * @return >=0 on success, -1 on error.
187
+ * @see dst_blacklist_su_to.
105 188
  */
106
-#define dst_blacklist_su(err_flags, proto, dst, msg) \
107
-	dst_blacklist_su_to((err_flags), (proto), (dst), (msg), \
108
-		S_TO_TICKS(cfg_get(core, core_cfg, blst_timeout)))
189
+#define dst_blacklist_su(err_flags, proto, dst, snd_flags, msg) \
190
+	dst_blacklist_su_to(err_flags, proto, dst, snd_flags, msg, \
191
+							S_TO_TICKS(cfg_get(core, core_cfg, blst_timeout)))
109 192
 
110 193
 int dst_is_blacklisted(struct dest_info* si, struct sip_msg* msg);
111 194
 /* delete an entry from the blacklist */
... ...
@@ -541,8 +541,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
541 541
 		if (msg_send(send_info, buf, len)<0){
542 542
 			ret=ser_error=E_SEND;
543 543
 #ifdef USE_DST_BLACKLIST
544
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
545
-				dst_blacklist_add(BLST_ERR_SEND, send_info, msg);
544
+			dst_blacklist_add(BLST_ERR_SEND, send_info, msg);
546 545
 #endif
547 546
 #ifdef USE_DNS_FAILOVER
548 547
 			continue; /* try another ip */
... ...
@@ -698,7 +697,7 @@ int forward_reply(struct sip_msg* msg)
698 698
 	}
699 699
 
700 700
 	dst.proto=msg->via2->proto;
701
-	dst.send_flags.f=msg->fwd_send_flags.f | msg->rpl_send_flags.f;
701
+	SND_FLAGS_OR(&dst.send_flags, &msg->fwd_send_flags, &msg->rpl_send_flags);
702 702
 	if (update_sock_struct_from_via( &dst.to, msg, msg->via2 )==-1) goto error;
703 703
 #ifdef USE_COMP
704 704
 	dst.comp=msg->via2->comp_no;
... ...
@@ -2126,13 +2126,12 @@ static int sctp_handle_send_failed(struct socket_info* si,
2126 2126
 		ret=sctp_msg_send_ext(&dst, data, data_len, &sinfo);
2127 2127
 	}
2128 2128
 #ifdef USE_DST_BLACKLIST
2129
-	 else if (cfg_get(core, core_cfg, use_dst_blacklist) &&
2130
-					cfg_get(sctp, sctp_cfg, send_retries)) {
2129
+	 else if (cfg_get(sctp, sctp_cfg, send_retries)) {
2131 2130
 		/* blacklist only if send_retries is on, if off we blacklist
2132 2131
 		   from SCTP_ASSOC_CHANGE: SCTP_COMM_LOST/SCTP_CANT_STR_ASSOC
2133 2132
 		   which is better (because we can tell connect errors from send
2134 2133
 		   errors and we blacklist a failed dst only once) */
2135
-		dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0);
2134
+		dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0, 0);
2136 2135
 	}
2137 2136
 #endif /* USE_DST_BLACKLIST */
2138 2137
 	
... ...
@@ -2213,9 +2212,8 @@ again:
2213 2213
 #ifdef USE_DST_BLACKLIST
2214 2214
 			/* blacklist only if send_retries is turned off (if on we don't
2215 2215
 			   know here if we did retry or we are at the first error) */
2216
-			if (cfg_get(core, core_cfg, use_dst_blacklist) &&
2217
-					(cfg_get(sctp, sctp_cfg, send_retries)==0))
2218
-						dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0);
2216
+			if (cfg_get(sctp, sctp_cfg, send_retries)==0)
2217
+						dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0, 0);
2219 2218
 #endif /* USE_DST_BLACKLIST */
2220 2219
 			/* no break */
2221 2220
 		case SCTP_SHUTDOWN_COMP:
... ...
@@ -2243,9 +2241,8 @@ again:
2243 2243
 #ifdef USE_DST_BLACKLIST
2244 2244
 			/* blacklist only if send_retries is turned off (if on we don't 
2245 2245
 			   know here if we did retry or we are at the first error) */
2246
-			if (cfg_get(core, core_cfg, use_dst_blacklist) &&
2247
-					(cfg_get(sctp, sctp_cfg, send_retries)==0))
2248
-						dst_blacklist_su(BLST_ERR_CONNECT, PROTO_SCTP, su, 0);
2246
+			if (cfg_get(sctp, sctp_cfg, send_retries)==0)
2247
+					dst_blacklist_su(BLST_ERR_CONNECT, PROTO_SCTP, su, 0, 0);
2249 2248
 #endif /* USE_DST_BLACKLIST */
2250 2249
 			break;
2251 2250
 		default:
... ...
@@ -193,10 +193,7 @@ struct tcp_connection{
193 193
 /* helper macros */
194 194
 
195 195
 #define tcpconn_set_send_flags(c, snd_flags) \
196
-	do{ \
197
-		(c)->send_flags.f|=(snd_flags).f; \
198
-		(c)->send_flags.blst_imask|=(snd_flags).blst_imask; \
199
-	}while(0)
196
+	SND_FLAGS_OR(&(c)->send_flags, &(c)->send_flags, &(snd_flags))
200 197
 
201 198
 #define tcpconn_close_after_send(c)	((c)->send_flags.f & SND_F_CON_CLOSE)
202 199
 
... ...
@@ -477,7 +477,7 @@ error:
477 477
  * if BLOCKING_USE_SELECT and HAVE_SELECT are defined it will internally
478 478
  * use select() instead of poll (bad if fd > FD_SET_SIZE, poll is preferred)
479 479
  */
480
-static int tcp_blocking_connect(int fd, int type,
480
+static int tcp_blocking_connect(int fd, int type, snd_flags_t* send_flags,
481 481
 								const struct sockaddr *servaddr,
482 482
 								socklen_t addrlen)
483 483
 {
... ...
@@ -570,18 +570,16 @@ error_errno:
570 570
 		case ENETUNREACH:
571 571
 		case EHOSTUNREACH:
572 572
 #ifdef USE_DST_BLACKLIST
573
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
574
-				dst_blacklist_su(BLST_ERR_CONNECT, type,
575
-							 (union sockaddr_union*)servaddr, 0);
573
+			dst_blacklist_su(BLST_ERR_CONNECT, type,
574
+							 (union sockaddr_union*)servaddr, send_flags, 0);
576 575
 #endif /* USE_DST_BLACKLIST */
577 576
 			TCP_EV_CONNECT_UNREACHABLE(errno, 0, 0,
578 577
 							(union sockaddr_union*)servaddr, type);
579 578
 			break;
580 579
 		case ETIMEDOUT:
581 580
 #ifdef USE_DST_BLACKLIST
582
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
583
-				dst_blacklist_su(BLST_ERR_CONNECT, type,
584
-								 (union sockaddr_union*)servaddr, 0);
581
+			dst_blacklist_su(BLST_ERR_CONNECT, type,
582
+							 (union sockaddr_union*)servaddr, send_flags, 0);
585 583
 #endif /* USE_DST_BLACKLIST */
586 584
 			TCP_EV_CONNECT_TIMEOUT(errno, 0, 0,
587 585
 							(union sockaddr_union*)servaddr, type);
... ...
@@ -589,9 +587,8 @@ error_errno:
589 589
 		case ECONNREFUSED:
590 590
 		case ECONNRESET:
591 591
 #ifdef USE_DST_BLACKLIST
592
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
593
-				dst_blacklist_su(BLST_ERR_CONNECT, type,
594
-								 (union sockaddr_union*)servaddr, 0);
592
+			dst_blacklist_su(BLST_ERR_CONNECT, type,
593
+							 (union sockaddr_union*)servaddr, send_flags, 0);
595 594
 #endif /* USE_DST_BLACKLIST */
596 595
 			TCP_EV_CONNECT_RST(errno, 0, 0,
597 596
 							(union sockaddr_union*)servaddr, type);
... ...
@@ -611,9 +608,8 @@ error_errno:
611 611
 error_timeout:
612 612
 	/* timeout */
613 613
 #ifdef USE_DST_BLACKLIST
614
-	if (cfg_get(core, core_cfg, use_dst_blacklist))
615
-		dst_blacklist_su(BLST_ERR_CONNECT, type,
616
-							(union sockaddr_union*)servaddr, 0);
614
+	dst_blacklist_su(BLST_ERR_CONNECT, type,
615
+						(union sockaddr_union*)servaddr, send_flags, 0);
617 616
 #endif /* USE_DST_BLACKLIST */
618 617
 	TCP_EV_CONNECT_TIMEOUT(0, 0, 0, (union sockaddr_union*)servaddr, type);
619 618
 	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,
666 666
 		if (q->first && TICKS_LT(q->wr_timeout, t)){
667 667
 			if (unlikely(c->state==S_CONN_CONNECT)){
668 668
 #ifdef USE_DST_BLACKLIST
669
-				if (likely(cfg_get(core, core_cfg, use_dst_blacklist))){
670
-					DBG("blacklisting, state=%d\n", c->state);
671
-					dst_blacklist_su( BLST_ERR_CONNECT, c->rcv.proto,
672
-										&c->rcv.src_su, 0);
673
-				}
669
+				dst_blacklist_su( BLST_ERR_CONNECT, c->rcv.proto,
670
+										&c->rcv.src_su, &c->send_flags, 0);
674 671
 #endif /* USE_DST_BLACKLIST */
675 672
 				TCP_EV_CONNECT_TIMEOUT(0, TCP_LADDR(c), TCP_LPORT(c),
676 673
 											TCP_PSU(c), TCP_PROTO(c));
677 674
 				TCP_STATS_CONNECT_FAILED();
678 675
 			}else{
679 676
 #ifdef USE_DST_BLACKLIST
680
-				if (likely(cfg_get(core, core_cfg, use_dst_blacklist))){
681
-					DBG("blacklisting, state=%d\n", c->state);
682
-					dst_blacklist_su( BLST_ERR_SEND, c->rcv.proto,
683
-										&c->rcv.src_su, 0);
684
-				}
677
+				dst_blacklist_su( BLST_ERR_SEND, c->rcv.proto,
678
+									&c->rcv.src_su, &c->send_flags, 0);
685 679
 #endif /* USE_DST_BLACKLIST */
686 680
 				TCP_EV_SEND_TIMEOUT(0, &c->rcv);
687 681
 				TCP_STATS_SEND_TIMEOUT();
... ...
@@ -865,10 +855,10 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
865 865
 							case ENETUNREACH:
866 866
 							case EHOSTUNREACH: /* not posix for send() */
867 867
 #ifdef USE_DST_BLACKLIST
868
-								if (cfg_get(core, core_cfg, use_dst_blacklist))
869
-									dst_blacklist_su(BLST_ERR_CONNECT,
870
-															c->rcv.proto,
871
-															&c->rcv.src_su, 0);
868
+								dst_blacklist_su(BLST_ERR_CONNECT,
869
+													c->rcv.proto,
870
+													&c->rcv.src_su,
871
+													&c->send_flags, 0);
872 872
 #endif /* USE_DST_BLACKLIST */
873 873
 								TCP_EV_CONNECT_UNREACHABLE(errno, TCP_LADDR(c),
874 874
 													TCP_LPORT(c), TCP_PSU(c),
... ...
@@ -877,10 +867,10 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
877 877
 							case ECONNREFUSED:
878 878
 							case ECONNRESET:
879 879
 #ifdef USE_DST_BLACKLIST
880
-								if (cfg_get(core, core_cfg, use_dst_blacklist))
881
-									dst_blacklist_su(BLST_ERR_CONNECT,
882
-															c->rcv.proto,
883
-															&c->rcv.src_su, 0);
880
+								dst_blacklist_su(BLST_ERR_CONNECT,
881
+													c->rcv.proto,
882
+													&c->rcv.src_su,
883
+													&c->send_flags, 0);
884 884
 #endif /* USE_DST_BLACKLIST */
885 885
 								TCP_EV_CONNECT_RST(0, TCP_LADDR(c),
886 886
 													TCP_LPORT(c), TCP_PSU(c),
... ...
@@ -901,10 +891,10 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
901 901
 							case ENETUNREACH:
902 902
 							case EHOSTUNREACH: /* not posix for send() */
903 903
 #ifdef USE_DST_BLACKLIST
904
-								if (cfg_get(core, core_cfg, use_dst_blacklist))
905
-									dst_blacklist_su(BLST_ERR_SEND,
906
-														c->rcv.proto,
907
-														&c->rcv.src_su, 0);
904
+								dst_blacklist_su(BLST_ERR_SEND,
905
+													c->rcv.proto,
906
+													&c->rcv.src_su,
907
+													&c->send_flags, 0);
908 908
 #endif /* USE_DST_BLACKLIST */
909 909
 								break;
910 910
 						}
... ...
@@ -1083,6 +1073,7 @@ error:
1083 1083
 inline static int tcp_do_connect(	union sockaddr_union* server,
1084 1084
 									union sockaddr_union* from,
1085 1085
 									int type,
1086
+									snd_flags_t* send_flags,
1086 1087
 									union sockaddr_union* res_local_addr,
1087 1088
 									struct socket_info** res_si,
1088 1089
 									enum tcp_conn_states *state
... ...
@@ -1127,23 +1118,23 @@ again:
1127 1127
 					case ENETUNREACH:
1128 1128
 					case EHOSTUNREACH:
1129 1129
 #ifdef USE_DST_BLACKLIST
1130
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
1131
-							dst_blacklist_su(BLST_ERR_CONNECT, type, server,0);
1130
+						dst_blacklist_su(BLST_ERR_CONNECT, type, server,
1131
+											send_flags, 0);
1132 1132
 #endif /* USE_DST_BLACKLIST */
1133 1133
 						TCP_EV_CONNECT_UNREACHABLE(errno, 0, 0, server, type);
1134 1134
 						break;
1135 1135
 					case ETIMEDOUT:
1136 1136
 #ifdef USE_DST_BLACKLIST
1137
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
1138
-							dst_blacklist_su(BLST_ERR_CONNECT, type, server,0);
1137
+						dst_blacklist_su(BLST_ERR_CONNECT, type, server,
1138
+											send_flags, 0);
1139 1139
 #endif /* USE_DST_BLACKLIST */
1140 1140
 						TCP_EV_CONNECT_TIMEOUT(errno, 0, 0, server, type);
1141 1141
 						break;
1142 1142
 					case ECONNREFUSED:
1143 1143
 					case ECONNRESET:
1144 1144
 #ifdef USE_DST_BLACKLIST
1145
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
1146
-							dst_blacklist_su(BLST_ERR_CONNECT, type, server,0);
1145
+						dst_blacklist_su(BLST_ERR_CONNECT, type, server,
1146
+											send_flags, 0);
1147 1147
 #endif /* USE_DST_BLACKLIST */
1148 1148
 						TCP_EV_CONNECT_RST(errno, 0, 0, server, type);
1149 1149
 						break;
... ...
@@ -1162,7 +1153,7 @@ again:
1162 1162
 		}
1163 1163
 	}else{
1164 1164
 #endif /* TCP_ASYNC */
1165
-		if (tcp_blocking_connect(s, type, &server->s,
1165
+		if (tcp_blocking_connect(s, type,  send_flags, &server->s,
1166 1166
 									sockaddru_len(*server))<0){
1167 1167
 			LOG(L_ERR, "ERROR: tcp_do_connect: tcp_blocking_connect %s"
1168 1168
 						" failed\n", su2a(server, sizeof(*server)));
... ...
@@ -1212,9 +1203,9 @@ error:
1212 1212
 
1213 1213
 
1214 1214
 
1215
-struct tcp_connection* tcpconn_connect( union sockaddr_union* server, 
1215
+struct tcp_connection* tcpconn_connect( union sockaddr_union* server,
1216 1216
 										union sockaddr_union* from,
1217
-										int type)
1217
+										int type, snd_flags_t* send_flags)
1218 1218
 {
1219 1219
 	int s;
1220 1220
 	struct socket_info* si;
... ...
@@ -1231,7 +1222,7 @@ struct tcp_connection* tcpconn_connect( union sockaddr_union* server,
1231 1231
 					cfg_get(tcp, tcp_cfg, max_connections));
1232 1232
 		goto error;
1233 1233
 	}
1234
-	s=tcp_do_connect(server, from, type, &my_name, &si, &state);
1234
+	s=tcp_do_connect(server, from, type,  send_flags, &my_name, &si, &state);
1235 1235
 	if (s==-1){
1236 1236
 		LOG(L_ERR, "ERROR: tcp_do_connect %s: failed (%d) %s\n",
1237 1237
 				su2a(server, sizeof(*server)), errno, strerror(errno));
... ...
@@ -1243,6 +1234,7 @@ struct tcp_connection* tcpconn_connect( union sockaddr_union* server,
1243 1243
 				 " socket\n", su2a(server, sizeof(*server)));
1244 1244
 		goto error;
1245 1245
 	}
1246
+	tcpconn_set_send_flags(con, *send_flags);
1246 1247
 	return con;
1247 1248
 	/*FIXME: set sock idx! */
1248 1249
 error:
... ...
@@ -1264,7 +1256,8 @@ int tcpconn_finish_connect( struct tcp_connection* c,
1264 1264
 	struct tcp_conn_alias* a;
1265 1265
 	int new_conn_alias_flags;
1266 1266
 	
1267
-	s=tcp_do_connect(&c->rcv.src_su, from, c->type, &local_addr, &si, &state);
1267
+	s=tcp_do_connect(&c->rcv.src_su, from, c->type, &c->send_flags,
1268
+						&local_addr, &si, &state);
1268 1269
 	if (unlikely(s==-1)){
1269 1270
 		LOG(L_ERR, "ERROR: tcpconn_finish_connect %s: tcp_do_connect for %p"
1270 1271
 					" 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,
1898 1898
 						case ENETUNREACH:
1899 1899
 						case EHOSTUNREACH:  /* not posix for send() */
1900 1900
 #ifdef USE_DST_BLACKLIST
1901
-							if (cfg_get(core, core_cfg, use_dst_blacklist))
1902
-								dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
1901
+							dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
1903 1902
 #endif /* USE_DST_BLACKLIST */
1904 1903
 							TCP_EV_CONNECT_UNREACHABLE(errno, TCP_LADDR(c),
1905 1904
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
... ...
@@ -1907,8 +1899,7 @@ int tcp_send(struct dest_info* dst, union sockaddr_union* from,
1907 1907
 						case ECONNREFUSED:
1908 1908
 						case ECONNRESET:
1909 1909
 #ifdef USE_DST_BLACKLIST
1910
-							if (cfg_get(core, core_cfg, use_dst_blacklist))
1911
-								dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
1910
+							dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
1912 1911
 #endif /* USE_DST_BLACKLIST */
1913 1912
 							TCP_EV_CONNECT_RST(errno, TCP_LADDR(c),
1914 1913
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
... ...
@@ -1950,7 +1941,8 @@ int tcp_send(struct dest_info* dst, union sockaddr_union* from,
1950 1950
 				goto end;
1951 1951
 			}
1952 1952
 #endif /* TCP_CONNECT_WAIT  && TCP_ASYNC */
1953
-			if (unlikely((c=tcpconn_connect(&dst->to, from, dst->proto))==0)){
1953
+			if (unlikely((c=tcpconn_connect(&dst->to, from, dst->proto,
1954
+											&dst->send_flags))==0)){
1954 1955
 				LOG(L_ERR, "ERROR: tcp_send %s: connect failed\n",
1955 1956
 								su2a(&dst->to, sizeof(dst->to)));
1956 1957
 				return -1;
... ...
@@ -2143,9 +2135,8 @@ send_it:
2143 2143
 				case ENETUNREACH:
2144 2144
 				case EHOSTUNREACH: /* not posix for send() */
2145 2145
 #ifdef USE_DST_BLACKLIST
2146
-					if (cfg_get(core, core_cfg, use_dst_blacklist))
2147
-						dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
2148
-											&c->rcv.src_su, 0);
2146
+					dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
2147
+										&c->rcv.src_su, &c->send_flags, 0);
2149 2148
 #endif /* USE_DST_BLACKLIST */
2150 2149
 					TCP_EV_CONNECT_UNREACHABLE(errno, TCP_LADDR(c),
2151 2150
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
... ...
@@ -2153,9 +2144,8 @@ send_it:
2153 2153
 				case ECONNREFUSED:
2154 2154
 				case ECONNRESET:
2155 2155
 #ifdef USE_DST_BLACKLIST
2156
-					if (cfg_get(core, core_cfg, use_dst_blacklist))
2157
-						dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
2158
-											&c->rcv.src_su, 0);
2156
+					dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
2157
+										&c->rcv.src_su, &c->send_flags, 0);
2159 2158
 #endif /* USE_DST_BLACKLIST */
2160 2159
 					TCP_EV_CONNECT_RST(errno, TCP_LADDR(c), TCP_LPORT(c),
2161 2160
 										TCP_PSU(c), TCP_PROTO(c));
... ...
@@ -2174,9 +2164,8 @@ send_it:
2174 2174
 				case ENETUNREACH:
2175 2175
 				/*case EHOSTUNREACH: -- not posix */
2176 2176
 #ifdef USE_DST_BLACKLIST
2177
-					if (cfg_get(core, core_cfg, use_dst_blacklist))
2178
-						dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
2179
-												&c->rcv.src_su, 0);
2177
+					dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
2178
+										&c->rcv.src_su, &c->send_flags, 0);
2180 2179
 #endif /* USE_DST_BLACKLIST */
2181 2180
 					break;
2182 2181
 			}
... ...
@@ -2896,10 +2885,10 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
2896 2896
 					/* timeout */
2897 2897
 					if (unlikely(tcpconn->state==S_CONN_CONNECT)){
2898 2898
 #ifdef USE_DST_BLACKLIST
2899
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
2900
-							dst_blacklist_su( BLST_ERR_CONNECT,
2901
-													tcpconn->rcv.proto,
2902
-													&tcpconn->rcv.src_su, 0);
2899
+						dst_blacklist_su( BLST_ERR_CONNECT,
2900
+											tcpconn->rcv.proto,
2901
+											&tcpconn->rcv.src_su,
2902
+											&tcpconn->send_flags, 0);
2903 2903
 #endif /* USE_DST_BLACKLIST */
2904 2904
 						TCP_EV_CONNECT_TIMEOUT(0, TCP_LADDR(tcpconn),
2905 2905
 										TCP_LPORT(tcpconn), TCP_PSU(tcpconn),
... ...
@@ -2907,10 +2896,10 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
2907 2907
 						TCP_STATS_CONNECT_FAILED();
2908 2908
 					}else{
2909 2909
 #ifdef USE_DST_BLACKLIST
2910
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
2911
-							dst_blacklist_su( BLST_ERR_SEND,
2912
-													tcpconn->rcv.proto,
2913
-													&tcpconn->rcv.src_su, 0);
2910
+						dst_blacklist_su( BLST_ERR_SEND,
2911
+											tcpconn->rcv.proto,
2912
+											&tcpconn->rcv.src_su,
2913
+											&tcpconn->send_flags, 0);
2914 2914
 #endif /* USE_DST_BLACKLIST */
2915 2915
 						TCP_EV_SEND_TIMEOUT(0, &tcpconn->rcv);
2916 2916
 						TCP_STATS_SEND_TIMEOUT();
... ...
@@ -3553,9 +3542,9 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, short ev,
3553 3553
 			if (unlikely(ev & POLLERR)){
3554 3554
 				if (unlikely(tcpconn->state==S_CONN_CONNECT)){
3555 3555
 #ifdef USE_DST_BLACKLIST
3556
-					if (cfg_get(core, core_cfg, use_dst_blacklist))
3557
-						dst_blacklist_su(BLST_ERR_CONNECT, tcpconn->rcv.proto,
3558
-											&tcpconn->rcv.src_su, 0);
3556
+					dst_blacklist_su(BLST_ERR_CONNECT, tcpconn->rcv.proto,
3557
+										&tcpconn->rcv.src_su,
3558
+										&tcpconn->send_flags, 0);
3559 3559
 #endif /* USE_DST_BLACKLIST */
3560 3560
 					TCP_EV_CONNECT_ERR(0, TCP_LADDR(tcpconn),
3561 3561
 										TCP_LPORT(tcpconn), TCP_PSU(tcpconn),
... ...
@@ -3563,9 +3552,9 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, short ev,
3563 3563
 					TCP_STATS_CONNECT_FAILED();
3564 3564
 				}else{
3565 3565
 #ifdef USE_DST_BLACKLIST
3566
-					if (cfg_get(core, core_cfg, use_dst_blacklist))
3567
-						dst_blacklist_su(BLST_ERR_SEND, tcpconn->rcv.proto,
3568
-											&tcpconn->rcv.src_su, 0);
3566
+					dst_blacklist_su(BLST_ERR_SEND, tcpconn->rcv.proto,
3567
+										&tcpconn->rcv.src_su,
3568
+										&tcpconn->send_flags, 0);
3569 3569
 #endif /* USE_DST_BLACKLIST */
3570 3570
 					TCP_STATS_CON_RESET(); /* FIXME: it could != RST */
3571 3571
 				}
... ...
@@ -3740,18 +3729,16 @@ static ticks_t tcpconn_main_timeout(ticks_t t, struct timer_ln* tl, void* data)
3740 3740
 	if (tcp_async && _wbufq_non_empty(c) && TICKS_GE(t, c->wbuf_q.wr_timeout)){
3741 3741
 		if (unlikely(c->state==S_CONN_CONNECT)){
3742 3742
 #ifdef USE_DST_BLACKLIST
3743
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
3744
-				dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
3745
-									&c->rcv.src_su, 0);
3743
+			dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto, &c->rcv.src_su,
3744
+								&c->send_flags, 0);
3746 3745
 #endif /* USE_DST_BLACKLIST */
3747 3746
 			TCP_EV_CONNECT_TIMEOUT(0, TCP_LADDR(c), TCP_LPORT(c), TCP_PSU(c),
3748 3747
 									TCP_PROTO(c));
3749 3748
 			TCP_STATS_CONNECT_FAILED();
3750 3749
 		}else{
3751 3750
 #ifdef USE_DST_BLACKLIST
3752
-			if (cfg_get(core, core_cfg, use_dst_blacklist))
3753
-				dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
3754
-									&c->rcv.src_su, 0);
3751
+			dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto, &c->rcv.src_su,
3752
+								&c->send_flags, 0);
3755 3753
 #endif /* USE_DST_BLACKLIST */
3756 3754
 			TCP_EV_SEND_TIMEOUT(0, &c->rcv);
3757 3755
 			TCP_STATS_SEND_TIMEOUT();
... ...
@@ -153,20 +153,18 @@ again:
153 153
 					switch(errno){
154 154
 						case ECONNRESET:
155 155
 #ifdef USE_DST_BLACKLIST
156
-							if (cfg_get(core, core_cfg, use_dst_blacklist))
157
-								dst_blacklist_su(BLST_ERR_CONNECT,
158
-														c->rcv.proto,
159
-														&c->rcv.src_su, 0);
156
+							dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
157
+												&c->rcv.src_su,
158
+												&c->send_flags, 0);
160 159
 #endif /* USE_DST_BLACKLIST */
161 160
 							TCP_EV_CONNECT_RST(errno, TCP_LADDR(c),
162 161
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
163 162
 							break;
164 163
 						case ETIMEDOUT:
165 164
 #ifdef USE_DST_BLACKLIST
166
-							if (cfg_get(core, core_cfg, use_dst_blacklist))
167
-								dst_blacklist_su(BLST_ERR_CONNECT,
168
-														c->rcv.proto,
169
-														&c->rcv.src_su, 0);
165
+							dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
166
+												&c->rcv.src_su,
167
+												&c->send_flags, 0);
170 168
 #endif /* USE_DST_BLACKLIST */
171 169
 							TCP_EV_CONNECT_TIMEOUT(errno, TCP_LADDR(c),
172 170
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
... ...
@@ -182,10 +180,9 @@ again:
182 182
 								TCP_STATS_CON_RESET();
183 183
 							case ETIMEDOUT:
184 184
 #ifdef USE_DST_BLACKLIST
185
-								if (cfg_get(core, core_cfg, use_dst_blacklist))
186
-									dst_blacklist_su(BLST_ERR_SEND,
187
-														c->rcv.proto,
188
-														&c->rcv.src_su, 0);
185
+								dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
186
+													&c->rcv.src_su,
187
+													&c->send_flags, 0);
189 188
 #endif /* USE_DST_BLACKLIST */
190 189
 								break;
191 190
 						}