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 87
 void destroy_dst_blacklist();
86 88
 
87 89
 
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);
90
+/** force add to the blacklist.
91
+ * like @function dst_blacklist_add_to, but no ignore mask or
92
+ * blacklist enabled checks are made.
93
+ * @see dst_blacklist_add_to for the parameters and return value.
94
+ */
95
+int dst_blacklist_force_add_to(unsigned char err_flags, struct dest_info* si,
96
+								struct sip_msg* msg, ticks_t timeout);
95 97
 
96
-/** adds a dst to the blacklist with default timeout.
97
- * @see dst_blacklist_add_to for more details.
98
+/** force add to the blacklist, long version.
99
+ * like @function dst_blacklist_su_to, but no ignore mask or
100
+ * blacklist enabled checks are made.
101
+ * @see dst_blacklist_su_to for the parameters and return value.
98 102
  */
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)))
103
+int dst_blacklist_force_su_to(	unsigned char err_flags,
104
+								unsigned char proto,
105
+								union sockaddr_union* dst,
106
+								struct sip_msg* msg,
107
+								ticks_t timeout);
108
+
109
+
110
+/** checks if blacklist should be used.
111
+  * @param  err_flags - blacklist reason
112
+  * @param si - filled dst_info structure pointer.
113
+  * @return 1 if blacklist is enabled (core_cfg) and the event/error
114
+  *           is not in the ignore list.
115
+  *         0 otherwise
116
+  */
117
+#define should_blacklist(err_flags, si) \
118
+	(cfg_get(core, core_cfg, use_dst_blacklist) && \
119
+		((err_flags) & (si)->send_flags.blst_imask))
120
+
121
+
122
+/** checks if blacklist should be used, long version.
123
+  * @param  err_flags - blacklist reason
124
+  * @param snd_flags - snd_flags pointer, can be 0.
125
+  * @param proto - protocol, can be 0 (PROTO_NONE).
126
+  * @param si  - sockaddr_union pointer, can be 0.
127
+  * @return 1 if blacklist is enabled (core_cfg) and the event/error
128
+  *           is not in the ignore list.
129
+  *         0 otherwise
130
+  */
131
+#define should_blacklist_su(err_flags, snd_flags, proto, su) \
132
+	(cfg_get(core, core_cfg, use_dst_blacklist) && \
133
+		((err_flags) & \
134
+		 			~((snd_flags)?((snd_flags_t*)(snd_flags))->blst_imask:0)))
135
+
136
+
137
+/** adds a dst to the blacklist.
138
+ *
139
+ * @param  err_flags - blacklist reason
140
+ * @param si  - dest_info structure (dst).
141
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
142
+ * @param timeout - timeout in ticks.
143
+ * @return >=0 on success, -1 on error.
144
+ */
145
+#define dst_blacklist_add_to(err_flags, si, msg, timeout) \
146
+	(should_blacklist(err_flags, si)? \
147
+		dst_blacklist_force_add_to((err_flags), (si), (msg), (timeout))\
148
+		: 0)
149
+
150
+
151
+/** adds a dst to the blacklist, long version.
152
+ * Similar to dst_blacklist_add_to, but uses "unpacked" parameters.
153
+ * @param  err_flags - blacklist reason
154
+ * @param proto - protocol.
155
+ * @param dst  - sockaddr_union pointer.
156
+ * @param snd_flags - snd_flags pointer, can be 0.
157
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
158
+ * @param timeout - timeout in ticks.
159
+ * @return >=0 on success, -1 on error.
160
+ */
161
+#define dst_blacklist_su_to(err_flags, proto, dst, snd_flags, msg, timeout) \
162
+	(should_blacklist_su(err_flags, snd_flags, proto, dst) ? \
163
+		dst_blacklist_force_su_to((err_flags), (proto), (dst), (msg), \
164
+									(timeout))\
165
+		: 0)
166
+
102 167
 
103 168
 /** adds a dst to the blacklist with default timeout.
104
- * @see dst_blacklist_su_to for more details.
169
+ *
170
+ * @param  err_flags - blacklist reason
171
+ * @param si  - dest_info structure (dst).
172
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
173
+ * @return >=0 on success, -1 on error.
174
+ * @see dst_blacklist_add_to.
175
+ */
176
+#define dst_blacklist_add(err_flags, si, msg) \
177
+	dst_blacklist_add_to(err_flags, si, msg, \
178
+							S_TO_TICKS(cfg_get(core, core_cfg, blst_timeout)))
179
+
180
+
181
+/** adds a dst to the blacklist with default timeout, long version.
182
+ * Similar to dst_blacklist_add_to, but uses "unpacked" parameters.
183
+ * @param  err_flags - blacklist reason
184
+ * @param proto - protocol.
185
+ * @param dst  - sockaddr_union pointer.
186
+ * @param snd_flags - snd_flags pointer, can be 0.
187
+ * @param msg - sip msg struct. pointer if known, 0 otherwise.
188
+ * @return >=0 on success, -1 on error.
189
+ * @see dst_blacklist_su_to.
105 190
  */
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)))
191
+#define dst_blacklist_su(err_flags, proto, dst, snd_flags, msg) \
192
+	dst_blacklist_su_to(err_flags, proto, dst, snd_flags, msg, \
193
+							S_TO_TICKS(cfg_get(core, core_cfg, blst_timeout)))
109 194
 
110 195
 int dst_is_blacklisted(struct dest_info* si, struct sip_msg* msg);
111 196
 /* 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 697
 	}
699 698
 
700 699
 	dst.proto=msg->via2->proto;
701
-	dst.send_flags.f=msg->fwd_send_flags.f | msg->rpl_send_flags.f;
700
+	SND_FLAGS_OR(&dst.send_flags, &msg->fwd_send_flags, &msg->rpl_send_flags);
702 701
 	if (update_sock_struct_from_via( &dst.to, msg, msg->via2 )==-1) goto error;
703 702
 #ifdef USE_COMP
704 703
 	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 2212
 #ifdef USE_DST_BLACKLIST
2214 2213
 			/* blacklist only if send_retries is turned off (if on we don't
2215 2214
 			   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);
2215
+			if (cfg_get(sctp, sctp_cfg, send_retries)==0)
2216
+						dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0, 0);
2219 2217
 #endif /* USE_DST_BLACKLIST */
2220 2218
 			/* no break */
2221 2219
 		case SCTP_SHUTDOWN_COMP:
... ...
@@ -2243,9 +2241,8 @@ again:
2243 2241
 #ifdef USE_DST_BLACKLIST
2244 2242
 			/* blacklist only if send_retries is turned off (if on we don't 
2245 2243
 			   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);
2244
+			if (cfg_get(sctp, sctp_cfg, send_retries)==0)
2245
+					dst_blacklist_su(BLST_ERR_CONNECT, PROTO_SCTP, su, 0, 0);
2249 2246
 #endif /* USE_DST_BLACKLIST */
2250 2247
 			break;
2251 2248
 		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 587
 		case ECONNREFUSED:
590 588
 		case ECONNRESET:
591 589
 #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);
590
+			dst_blacklist_su(BLST_ERR_CONNECT, type,
591
+							 (union sockaddr_union*)servaddr, send_flags, 0);
595 592
 #endif /* USE_DST_BLACKLIST */
596 593
 			TCP_EV_CONNECT_RST(errno, 0, 0,
597 594
 							(union sockaddr_union*)servaddr, type);
... ...
@@ -611,9 +608,8 @@ error_errno:
611 608
 error_timeout:
612 609
 	/* timeout */
613 610
 #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);
611
+	dst_blacklist_su(BLST_ERR_CONNECT, type,
612
+						(union sockaddr_union*)servaddr, send_flags, 0);
617 613
 #endif /* USE_DST_BLACKLIST */
618 614
 	TCP_EV_CONNECT_TIMEOUT(0, 0, 0, (union sockaddr_union*)servaddr, type);
619 615
 	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 662
 		if (q->first && TICKS_LT(q->wr_timeout, t)){
667 663
 			if (unlikely(c->state==S_CONN_CONNECT)){
668 664
 #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
-				}
665
+				dst_blacklist_su( BLST_ERR_CONNECT, c->rcv.proto,
666
+										&c->rcv.src_su, &c->send_flags, 0);
674 667
 #endif /* USE_DST_BLACKLIST */
675 668
 				TCP_EV_CONNECT_TIMEOUT(0, TCP_LADDR(c), TCP_LPORT(c),
676 669
 											TCP_PSU(c), TCP_PROTO(c));
677 670
 				TCP_STATS_CONNECT_FAILED();
678 671
 			}else{
679 672
 #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
-				}
673
+				dst_blacklist_su( BLST_ERR_SEND, c->rcv.proto,
674
+									&c->rcv.src_su, &c->send_flags, 0);
685 675
 #endif /* USE_DST_BLACKLIST */
686 676
 				TCP_EV_SEND_TIMEOUT(0, &c->rcv);
687 677
 				TCP_STATS_SEND_TIMEOUT();
... ...
@@ -865,10 +855,10 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
865 855
 							case ENETUNREACH:
866 856
 							case EHOSTUNREACH: /* not posix for send() */
867 857
 #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);
858
+								dst_blacklist_su(BLST_ERR_CONNECT,
859
+													c->rcv.proto,
860
+													&c->rcv.src_su,
861
+													&c->send_flags, 0);
872 862
 #endif /* USE_DST_BLACKLIST */
873 863
 								TCP_EV_CONNECT_UNREACHABLE(errno, TCP_LADDR(c),
874 864
 													TCP_LPORT(c), TCP_PSU(c),
... ...
@@ -877,10 +867,10 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
877 867
 							case ECONNREFUSED:
878 868
 							case ECONNRESET:
879 869
 #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);
870
+								dst_blacklist_su(BLST_ERR_CONNECT,
871
+													c->rcv.proto,
872
+													&c->rcv.src_su,
873
+													&c->send_flags, 0);
884 874
 #endif /* USE_DST_BLACKLIST */
885 875
 								TCP_EV_CONNECT_RST(0, TCP_LADDR(c),
886 876
 													TCP_LPORT(c), TCP_PSU(c),
... ...
@@ -901,10 +891,10 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
901 891
 							case ENETUNREACH:
902 892
 							case EHOSTUNREACH: /* not posix for send() */
903 893
 #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);
894
+								dst_blacklist_su(BLST_ERR_SEND,
895
+													c->rcv.proto,
896
+													&c->rcv.src_su,
897
+													&c->send_flags, 0);
908 898
 #endif /* USE_DST_BLACKLIST */
909 899
 								break;
910 900
 						}
... ...
@@ -1083,6 +1073,7 @@ error:
1083 1073
 inline static int tcp_do_connect(	union sockaddr_union* server,
1084 1074
 									union sockaddr_union* from,
1085 1075
 									int type,
1076
+									snd_flags_t* send_flags,
1086 1077
 									union sockaddr_union* res_local_addr,
1087 1078
 									struct socket_info** res_si,
1088 1079
 									enum tcp_conn_states *state
... ...
@@ -1127,23 +1118,23 @@ again:
1127 1118
 					case ENETUNREACH:
1128 1119
 					case EHOSTUNREACH:
1129 1120
 #ifdef USE_DST_BLACKLIST
1130
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
1131
-							dst_blacklist_su(BLST_ERR_CONNECT, type, server,0);
1121
+						dst_blacklist_su(BLST_ERR_CONNECT, type, server,
1122
+											send_flags, 0);
1132 1123
 #endif /* USE_DST_BLACKLIST */
1133 1124
 						TCP_EV_CONNECT_UNREACHABLE(errno, 0, 0, server, type);
1134 1125
 						break;
1135 1126
 					case ETIMEDOUT:
1136 1127
 #ifdef USE_DST_BLACKLIST
1137
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
1138
-							dst_blacklist_su(BLST_ERR_CONNECT, type, server,0);
1128
+						dst_blacklist_su(BLST_ERR_CONNECT, type, server,
1129
+											send_flags, 0);
1139 1130
 #endif /* USE_DST_BLACKLIST */
1140 1131
 						TCP_EV_CONNECT_TIMEOUT(errno, 0, 0, server, type);
1141 1132
 						break;
1142 1133
 					case ECONNREFUSED:
1143 1134
 					case ECONNRESET:
1144 1135
 #ifdef USE_DST_BLACKLIST
1145
-						if (cfg_get(core, core_cfg, use_dst_blacklist))
1146
-							dst_blacklist_su(BLST_ERR_CONNECT, type, server,0);
1136
+						dst_blacklist_su(BLST_ERR_CONNECT, type, server,
1137
+											send_flags, 0);
1147 1138
 #endif /* USE_DST_BLACKLIST */
1148 1139
 						TCP_EV_CONNECT_RST(errno, 0, 0, server, type);
1149 1140
 						break;
... ...
@@ -1162,7 +1153,7 @@ again:
1162 1153
 		}
1163 1154
 	}else{
1164 1155
 #endif /* TCP_ASYNC */
1165
-		if (tcp_blocking_connect(s, type, &server->s,
1156
+		if (tcp_blocking_connect(s, type,  send_flags, &server->s,
1166 1157
 									sockaddru_len(*server))<0){
1167 1158
 			LOG(L_ERR, "ERROR: tcp_do_connect: tcp_blocking_connect %s"
1168 1159
 						" failed\n", su2a(server, sizeof(*server)));
... ...
@@ -1212,9 +1203,9 @@ error:
1212 1203
 
1213 1204
 
1214 1205
 
1215
-struct tcp_connection* tcpconn_connect( union sockaddr_union* server, 
1206
+struct tcp_connection* tcpconn_connect( union sockaddr_union* server,
1216 1207
 										union sockaddr_union* from,
1217
-										int type)
1208
+										int type, snd_flags_t* send_flags)
1218 1209
 {
1219 1210
 	int s;
1220 1211
 	struct socket_info* si;
... ...
@@ -1231,7 +1222,7 @@ struct tcp_connection* tcpconn_connect( union sockaddr_union* server,
1231 1222
 					cfg_get(tcp, tcp_cfg, max_connections));
1232 1223
 		goto error;
1233 1224
 	}
1234
-	s=tcp_do_connect(server, from, type, &my_name, &si, &state);
1225
+	s=tcp_do_connect(server, from, type,  send_flags, &my_name, &si, &state);
1235 1226
 	if (s==-1){
1236 1227
 		LOG(L_ERR, "ERROR: tcp_do_connect %s: failed (%d) %s\n",
1237 1228
 				su2a(server, sizeof(*server)), errno, strerror(errno));
... ...
@@ -1243,6 +1234,7 @@ struct tcp_connection* tcpconn_connect( union sockaddr_union* server,
1243 1234
 				 " socket\n", su2a(server, sizeof(*server)));
1244 1235
 		goto error;
1245 1236
 	}
1237
+	tcpconn_set_send_flags(con, *send_flags);
1246 1238
 	return con;
1247 1239
 	/*FIXME: set sock idx! */
1248 1240
 error:
... ...
@@ -1264,7 +1256,8 @@ int tcpconn_finish_connect( struct tcp_connection* c,
1264 1256
 	struct tcp_conn_alias* a;
1265 1257
 	int new_conn_alias_flags;
1266 1258
 	
1267
-	s=tcp_do_connect(&c->rcv.src_su, from, c->type, &local_addr, &si, &state);
1259
+	s=tcp_do_connect(&c->rcv.src_su, from, c->type, &c->send_flags,
1260
+						&local_addr, &si, &state);
1268 1261
 	if (unlikely(s==-1)){
1269 1262
 		LOG(L_ERR, "ERROR: tcpconn_finish_connect %s: tcp_do_connect for %p"
1270 1263
 					" 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 1891
 						case ENETUNREACH:
1899 1892
 						case EHOSTUNREACH:  /* not posix for send() */
1900 1893
 #ifdef USE_DST_BLACKLIST
1901
-							if (cfg_get(core, core_cfg, use_dst_blacklist))
1902
-								dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
1894
+							dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
1903 1895
 #endif /* USE_DST_BLACKLIST */
1904 1896
 							TCP_EV_CONNECT_UNREACHABLE(errno, TCP_LADDR(c),
1905 1897
 									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 1899
 						case ECONNREFUSED:
1908 1900
 						case ECONNRESET:
1909 1901
 #ifdef USE_DST_BLACKLIST
1910
-							if (cfg_get(core, core_cfg, use_dst_blacklist))
1911
-								dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
1902
+							dst_blacklist_add( BLST_ERR_CONNECT, dst, 0);
1912 1903
 #endif /* USE_DST_BLACKLIST */
1913 1904
 							TCP_EV_CONNECT_RST(errno, TCP_LADDR(c),
1914 1905
 									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 1941
 				goto end;
1951 1942
 			}
1952 1943
 #endif /* TCP_CONNECT_WAIT  && TCP_ASYNC */
1953
-			if (unlikely((c=tcpconn_connect(&dst->to, from, dst->proto))==0)){
1944
+			if (unlikely((c=tcpconn_connect(&dst->to, from, dst->proto,
1945
+											&dst->send_flags))==0)){
1954 1946
 				LOG(L_ERR, "ERROR: tcp_send %s: connect failed\n",
1955 1947
 								su2a(&dst->to, sizeof(dst->to)));
1956 1948
 				return -1;
... ...
@@ -2143,9 +2135,8 @@ send_it:
2143 2135
 				case ENETUNREACH:
2144 2136
 				case EHOSTUNREACH: /* not posix for send() */
2145 2137
 #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);
2138
+					dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
2139
+										&c->rcv.src_su, &c->send_flags, 0);
2149 2140
 #endif /* USE_DST_BLACKLIST */
2150 2141
 					TCP_EV_CONNECT_UNREACHABLE(errno, TCP_LADDR(c),
2151 2142
 									TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
... ...
@@ -2153,9 +2144,8 @@ send_it:
2153 2144
 				case ECONNREFUSED:
2154 2145
 				case ECONNRESET:
2155 2146
 #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);
2147
+					dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
2148
+										&c->rcv.src_su, &c->send_flags, 0);
2159 2149
 #endif /* USE_DST_BLACKLIST */
2160 2150
 					TCP_EV_CONNECT_RST(errno, TCP_LADDR(c), TCP_LPORT(c),
2161 2151
 										TCP_PSU(c), TCP_PROTO(c));
... ...
@@ -2174,9 +2164,8 @@ send_it:
2174 2164
 				case ENETUNREACH:
2175 2165
 				/*case EHOSTUNREACH: -- not posix */
2176 2166
 #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);
2167
+					dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
2168
+										&c->rcv.src_su, &c->send_flags, 0);
2180 2169
 #endif /* USE_DST_BLACKLIST */
2181 2170
 					break;
2182 2171
 			}
... ...
@@ -2896,10 +2885,10 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
2896 2885
 					/* timeout */
2897 2886
 					if (unlikely(tcpconn->state==S_CONN_CONNECT)){
2898 2887
 #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);
2888
+						dst_blacklist_su( BLST_ERR_CONNECT,
2889
+											tcpconn->rcv.proto,
2890
+											&tcpconn->rcv.src_su,
2891
+											&tcpconn->send_flags, 0);
2903 2892
 #endif /* USE_DST_BLACKLIST */
2904 2893
 						TCP_EV_CONNECT_TIMEOUT(0, TCP_LADDR(tcpconn),
2905 2894
 										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 2896
 						TCP_STATS_CONNECT_FAILED();
2908 2897
 					}else{
2909 2898
 #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);
2899
+						dst_blacklist_su( BLST_ERR_SEND,
2900
+											tcpconn->rcv.proto,
2901
+											&tcpconn->rcv.src_su,
2902
+											&tcpconn->send_flags, 0);
2914 2903
 #endif /* USE_DST_BLACKLIST */
2915 2904
 						TCP_EV_SEND_TIMEOUT(0, &tcpconn->rcv);
2916 2905
 						TCP_STATS_SEND_TIMEOUT();
... ...
@@ -3553,9 +3542,9 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, short ev,
3553 3542
 			if (unlikely(ev & POLLERR)){
3554 3543
 				if (unlikely(tcpconn->state==S_CONN_CONNECT)){
3555 3544
 #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);
3545
+					dst_blacklist_su(BLST_ERR_CONNECT, tcpconn->rcv.proto,
3546
+										&tcpconn->rcv.src_su,
3547
+										&tcpconn->send_flags, 0);
3559 3548
 #endif /* USE_DST_BLACKLIST */
3560 3549
 					TCP_EV_CONNECT_ERR(0, TCP_LADDR(tcpconn),
3561 3550
 										TCP_LPORT(tcpconn), TCP_PSU(tcpconn),
... ...
@@ -3563,9 +3552,9 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, short ev,
3563 3552
 					TCP_STATS_CONNECT_FAILED();
3564 3553
 				}else{
3565 3554
 #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);
3555
+					dst_blacklist_su(BLST_ERR_SEND, tcpconn->rcv.proto,
3556
+										&tcpconn->rcv.src_su,
3557
+										&tcpconn->send_flags, 0);
3569 3558
 #endif /* USE_DST_BLACKLIST */
3570 3559
 					TCP_STATS_CON_RESET(); /* FIXME: it could != RST */
3571 3560
 				}
... ...
@@ -3740,18 +3729,16 @@ static ticks_t tcpconn_main_timeout(ticks_t t, struct timer_ln* tl, void* data)
3740 3729
 	if (tcp_async && _wbufq_non_empty(c) && TICKS_GE(t, c->wbuf_q.wr_timeout)){
3741 3730
 		if (unlikely(c->state==S_CONN_CONNECT)){
3742 3731
 #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);
3732
+			dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto, &c->rcv.src_su,
3733
+								&c->send_flags, 0);
3746 3734
 #endif /* USE_DST_BLACKLIST */
3747 3735
 			TCP_EV_CONNECT_TIMEOUT(0, TCP_LADDR(c), TCP_LPORT(c), TCP_PSU(c),
3748 3736
 									TCP_PROTO(c));
3749 3737
 			TCP_STATS_CONNECT_FAILED();
3750 3738
 		}else{
3751 3739
 #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);
3740
+			dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto, &c->rcv.src_su,
3741
+								&c->send_flags, 0);
3755 3742
 #endif /* USE_DST_BLACKLIST */
3756 3743
 			TCP_EV_SEND_TIMEOUT(0, &c->rcv);
3757 3744
 			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 180
 								TCP_STATS_CON_RESET();
183 181
 							case ETIMEDOUT:
184 182
 #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);
183
+								dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
184
+													&c->rcv.src_su,
185
+													&c->send_flags, 0);
189 186
 #endif /* USE_DST_BLACKLIST */
190 187
 								break;
191 188
 						}