Browse code

core: tcp - helper function to send data over ws/wss connection

Daniel-Constantin Mierla authored on 09/10/2020 05:52:29
Showing 2 changed files
... ...
@@ -95,6 +95,7 @@
95 95
 #include "tcp_info.h"
96 96
 #include "tcp_options.h"
97 97
 #include "ut.h"
98
+#include "events.h"
98 99
 #include "cfg/cfg_struct.h"
99 100
 
100 101
 #include <fcntl.h> /* must be included after io_wait.h if SIGIO_RT is used */
... ...
@@ -5135,4 +5136,88 @@ void tcp_get_info(struct tcp_gen_info *ti)
5135 5136
 #endif /* TCP_ASYNC */
5136 5137
 }
5137 5138
 
5139
+
5140
+/* finds an ws/wss tcpconn & sends on it
5141
+ * uses the dst members to, proto (ws/wss) and id and tries to send
5142
+ * returns: number of bytes written (>=0) on success
5143
+ *          <0 on error */
5144
+int wss_send(dest_info_t* dst, const char* buf, unsigned len)
5145
+{
5146
+	int port;
5147
+	struct ip_addr ip;
5148
+	union sockaddr_union* from = NULL;
5149
+	union sockaddr_union local_addr;
5150
+	struct tcp_connection *con = NULL;
5151
+	struct ws_event_info wsev;
5152
+	sr_event_param_t evp = {0};
5153
+	int ret;
5154
+
5155
+	if (unlikely((dst->proto == PROTO_WS
5156
+#ifdef USE_TLS
5157
+					|| dst->proto == PROTO_WSS
5138 5158
 #endif
5159
+				) && sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) {
5160
+		if (unlikely(dst->send_flags.f & SND_F_FORCE_SOCKET
5161
+					&& dst->send_sock)) {
5162
+
5163
+			local_addr = dst->send_sock->su;
5164
+#ifdef SO_REUSEPORT
5165
+			if (cfg_get(tcp, tcp_cfg, reuse_port)) {
5166
+				LM_DBG("sending to: %s, force_socket=%d, send_sock=%p\n",
5167
+						su2a(&dst->to,sizeof(struct sockaddr_in)),
5168
+						(dst->send_flags.f & SND_F_FORCE_SOCKET),
5169
+						dst->send_sock);
5170
+
5171
+				su_setport(&local_addr, dst->send_sock->port_no);
5172
+			}
5173
+			else
5174
+				su_setport(&local_addr, 0); /* any local port will do */
5175
+#else
5176
+			su_setport(&local_addr, 0); /* any local port will do */
5177
+#endif
5178
+			from = &local_addr;
5179
+		}
5180
+
5181
+		port = su_getport(&dst->to);
5182
+		if (likely(port)) {
5183
+			su2ip_addr(&ip, &dst->to);
5184
+			if(tcp_connection_match==TCPCONN_MATCH_STRICT) {
5185
+				con = tcpconn_lookup(dst->id, &ip, port, from,
5186
+						(dst->send_sock)?dst->send_sock->port_no:0, 0);
5187
+			} else {
5188
+				con = tcpconn_get(dst->id, &ip, port, from, 0);
5189
+			}
5190
+		}
5191
+		else if (likely(dst->id))
5192
+			con = tcpconn_get(dst->id, 0, 0, 0, 0);
5193
+		else {
5194
+			LM_CRIT("null_id & to\n");
5195
+			goto error;
5196
+		}
5197
+
5198
+		if (con == NULL) {
5199
+			LM_WARN("TCP/TLS connection for WebSocket could not be found\n");
5200
+			goto error;
5201
+		}
5202
+
5203
+		memset(&wsev, 0, sizeof(ws_event_info_t));
5204
+		wsev.type = SREV_TCP_WS_FRAME_OUT;
5205
+		wsev.buf = (char*)buf;
5206
+		wsev.len = len;
5207
+		wsev.id = con->id;
5208
+		evp.data = (void *)&wsev;
5209
+		ret = sr_event_exec(SREV_TCP_WS_FRAME_OUT, &evp);
5210
+		tcpconn_put(con);
5211
+		goto done;
5212
+	} else {
5213
+		LM_CRIT("used with invalid proto %d\n", dst->proto);
5214
+		goto error;
5215
+	}
5216
+
5217
+done:
5218
+	return ret;
5219
+error:
5220
+	return -1;
5221
+}
5222
+
5223
+#endif /* USE_TCP */
... ...
@@ -13,8 +13,8 @@
13 13
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 14
  * GNU General Public License for more details.
15 15
  *
16
- * You should have received a copy of the GNU General Public License 
17
- * along with this program; if not, write to the Free Software 
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18 18
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19 19
  */
20 20
 
... ...
@@ -33,7 +33,7 @@ int tcp_send(struct dest_info* dst, union sockaddr_union* from,
33 33
 int tcpconn_add_alias(int id, int port, int proto);
34 34
 
35 35
 
36
-
36
+int wss_send(dest_info_t* dst, const char* buf, unsigned len);
37 37
 
38 38
 
39 39
 #endif