|
@@ -0,0 +1,64 @@
|
|
1
|
+#include <stdio.h>
|
|
2
|
+#include <stdlib.h>
|
|
3
|
+#include <string.h>
|
|
4
|
+#include <sys/types.h>
|
|
5
|
+#include <sys/stat.h>
|
|
6
|
+#include <unistd.h>
|
|
7
|
+#include <fcntl.h>
|
|
8
|
+#include <sys/socket.h>
|
|
9
|
+#include <netinet/in.h>
|
|
10
|
+#include <arpa/inet.h>
|
|
11
|
+#include <errno.h>
|
|
12
|
+
|
|
13
|
+#include "udp.h"
|
|
14
|
+
|
|
15
|
+static void set_sock_nonblock(int sockfd) {
|
|
16
|
+ int arg = fcntl(sockfd, F_GETFL, NULL);
|
|
17
|
+ arg |= O_NONBLOCK;
|
|
18
|
+ fcntl(sockfd, F_SETFL, arg);
|
|
19
|
+}
|
|
20
|
+
|
|
21
|
+int udp_connect_output(struct ts *ts) {
|
|
22
|
+ int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
23
|
+ if (sock < 0) {
|
|
24
|
+ ts_LOGf("socket(SOCK_DGRAM): %s\n", strerror(errno));
|
|
25
|
+ return -1;
|
|
26
|
+ }
|
|
27
|
+
|
|
28
|
+ ts_LOGf("Connecting output to udp://%s:%d ttl:%d\n",
|
|
29
|
+ inet_ntoa(ts->output_addr), ts->output_port, ts->output_ttl);
|
|
30
|
+
|
|
31
|
+ int on = 1;
|
|
32
|
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
|
33
|
+ set_sock_nonblock(sock);
|
|
34
|
+
|
|
35
|
+ // subscribe to multicast group
|
|
36
|
+ if (IN_MULTICAST(ntohl(ts->output_addr.s_addr))) {
|
|
37
|
+ int ttl = ts->output_ttl;
|
|
38
|
+ if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) {
|
|
39
|
+ ts_LOGf("setsockopt(IP_MUTICAST_TTL): %s\n", strerror(errno));
|
|
40
|
+ close(sock);
|
|
41
|
+ return -1;
|
|
42
|
+ }
|
|
43
|
+ if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &ts->output_intf, sizeof(ts->output_intf)) < 0) {
|
|
44
|
+ ts_LOGf("setsockopt(IP_MUTICAST_IF %s): %s\n", inet_ntoa(ts->output_intf), strerror(errno));
|
|
45
|
+ close(sock);
|
|
46
|
+ return -1;
|
|
47
|
+ }
|
|
48
|
+ }
|
|
49
|
+
|
|
50
|
+ struct sockaddr_in sockaddr;
|
|
51
|
+ memset(&sockaddr, 0, sizeof(sockaddr));
|
|
52
|
+ sockaddr.sin_family = AF_INET;
|
|
53
|
+ sockaddr.sin_addr.s_addr = ts->output_addr.s_addr;
|
|
54
|
+ sockaddr.sin_port = htons(ts->output_port);
|
|
55
|
+ if (connect(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
|
|
56
|
+ ts_LOGf("udp_connect() error: %s\n", strerror(errno));
|
|
57
|
+ close(sock);
|
|
58
|
+ return -1;
|
|
59
|
+ }
|
|
60
|
+ ts->output_fd = sock;
|
|
61
|
+ ts_LOGf("Output connected to fd:%d\n", ts->output_fd);
|
|
62
|
+
|
|
63
|
+ return 1;
|
|
64
|
+}
|