Browse code

core: enhanced get_send_socket() version

get_send_socket2() added.

Andrei Pelinescu-Onciul authored on 20/07/2009 21:51:27
Showing 2 changed files
... ...
@@ -151,43 +151,58 @@ error:
151 151
 
152 152
 
153 153
 
154
-/* returns a socket_info pointer to the sending socket or 0 on error
155
- * params: sip msg (can be null), destination socket_union pointer, protocol
156
- * if msg!=null and msg->force_send_socket, the force_send_socket will be
157
- * used
154
+/** get the sending socket for a corresponding destination.
155
+ * @param force_send_socket - if !=0 and the protocol and af correspond
156
+ *                            with the destination, it will be returned.
157
+ *                            If the protocol or af check fail, a look-alike
158
+ *                            socket will be searched for and mismatch will be
159
+ *                            set. If no look-alike socket is found it will
160
+ *                            fallback to normal resolution.
161
+ * @param to - destination
162
+ * @param proto - protocol
163
+ * @param mismatch - result parameter, set if a force_send_socket was used, but
164
+ *                   there was an error matching it exactly to the destination.
165
+ *                   Possible values: 0 ok, SS_MISMATCH_PROTO,
166
+ *                   SS_MISMATCH_ADDR, SS_MISMATCH_AF, SS_MISMATCH_MCAST.
167
+ * @return a socket_info pointer to the sending socket on success (and possibly
168
+ *         sets mismatch) or 0 on error.
158 169
  */
159
-struct socket_info* get_send_socket(struct sip_msg *msg, 
160
-										union sockaddr_union* to, int proto)
170
+struct socket_info* get_send_socket2(struct socket_info* force_send_socket,
171
+										union sockaddr_union* to, int proto,
172
+										enum ss_mismatch* mismatch)
161 173
 {
162 174
 	struct socket_info* send_sock;
163 175
 	
176
+	if (likely(mismatch)) *mismatch=0;
164 177
 	/* check if send interface is not forced */
165
-	if (unlikely(msg && msg->force_send_socket)){
166
-		if (unlikely(msg->force_send_socket->proto!=proto)){
167
-			DBG("get_send_socket: force_send_socket of different proto"
168
-					" (%d)!\n", proto);
169
-			msg->force_send_socket=find_si(&(msg->force_send_socket->address),
170
-											msg->force_send_socket->port_no,
178
+	if (unlikely(force_send_socket)){
179
+		if (unlikely(force_send_socket->proto!=proto)){
180
+			force_send_socket=find_si(&(force_send_socket->address),
181
+											force_send_socket->port_no,
171 182
 											proto);
172
-			if (unlikely(msg->force_send_socket == 0)){
183
+			if (unlikely(force_send_socket == 0)){
184
+				if (likely(mismatch)) *mismatch=SS_MISMATCH_ADDR;
173 185
 				LOG(L_WARN, "WARNING: get_send_socket: "
174 186
 						"protocol/port mismatch\n");
175 187
 				goto not_forced;
176 188
 			}
189
+			if (likely(mismatch)) *mismatch=SS_MISMATCH_PROTO;
177 190
 		}
178
-		if (unlikely(msg->force_send_socket->address.af!=to->s.sa_family)){
191
+		if (unlikely(force_send_socket->address.af!=to->s.sa_family)){
179 192
 			DBG("get_send_socket: force_send_socket of different af (dst %d,"
180 193
 					" forced %d)\n",
181
-					to->s.sa_family, msg->force_send_socket->address.af);
194
+					to->s.sa_family, force_send_socket->address.af);
195
+			if (likely(mismatch)) *mismatch=SS_MISMATCH_AF;
182 196
 			goto not_forced;
183 197
 		}
184
-		if (likely((msg->force_send_socket->socket!=-1) &&
185
-					!(msg->force_send_socket->flags & SI_IS_MCAST)))
186
-				return msg->force_send_socket;
198
+		if (likely((force_send_socket->socket!=-1) &&
199
+					!(force_send_socket->flags & SI_IS_MCAST)))
200
+				return force_send_socket;
187 201
 		else{
188
-			if (!(msg->force_send_socket->flags & SI_IS_MCAST))
202
+			if (!(force_send_socket->flags & SI_IS_MCAST))
189 203
 				LOG(L_WARN, "WARNING: get_send_socket: not listening"
190 204
 							 " on the requested socket, no fork mode?\n");
205
+			else if (likely(mismatch)) *mismatch=SS_MISMATCH_MCAST;
191 206
 		}
192 207
 	};
193 208
 not_forced:
... ...
@@ -62,9 +62,26 @@
62 62
 #include "compiler_opt.h"
63 63
 
64 64
 
65
+enum ss_mismatch {
66
+	SS_MISMATCH_OK=0,
67
+	SS_MISMATCH_PROTO, /* proto mismatch, but found same addr:port */
68
+	SS_MISMATCH_ADDR,  /* proto and addr:port mismatch */
69
+	SS_MISMATCH_AF,    /* af mismatch */
70
+	SS_MISMATCH_MCAST  /* mcast forced send socket */
71
+};
72
+
73
+struct socket_info* get_send_socket2(struct socket_info* force_send_socket,
74
+									union sockaddr_union* su, int proto,
75
+									enum ss_mismatch* mismatch);
76
+
77
+
78
+inline static struct socket_info* get_send_socket(struct sip_msg* msg,
79
+									union sockaddr_union* su, int proto)
80
+{
81
+	return get_send_socket2(msg?msg->force_send_socket:0, su, proto, 0);
82
+}
83
+
65 84
 
66
-struct socket_info* get_send_socket(struct sip_msg* msg,
67
-									union sockaddr_union* su, int proto);
68 85
 struct socket_info* get_out_socket(union sockaddr_union* to, int proto);
69 86
 int check_self(str* host, unsigned short port, unsigned short proto);
70 87
 int check_self_port(unsigned short port, unsigned short proto);