File: stream_udp.c

package info (click to toggle)
getstream 20070419-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 308 kB
  • ctags: 658
  • sloc: ansic: 4,137; makefile: 58
file content (72 lines) | stat: -rw-r--r-- 1,938 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

#include <sys/types.h>
#include <sys/socket.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "getstream.h"

int stream_init_udp(struct stream_s *s) {
	struct sockaddr_in	lsin, rsin;

	memset(&lsin, 0, sizeof(struct sockaddr_in));
	memset(&rsin, 0, sizeof(struct sockaddr_in));

	s->buffer=calloc(1, SOUT_UDP_PAYLOAD_MAX);
	if (s->buffer == NULL)
		return 0;

	s->sockfd=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

	/* Create local end sockaddr_in */
	lsin.sin_family=AF_INET;
	lsin.sin_port=0;
	lsin.sin_addr.s_addr=INADDR_ANY;
	bind(s->sockfd, (struct sockaddr *) &lsin, sizeof(struct sockaddr_in));

	/* Create remote end sockaddr_in */
	rsin.sin_family=AF_INET;
	rsin.sin_port=htons(s->remoteport);
	inet_aton(s->remoteaddr, &rsin.sin_addr);
	connect(s->sockfd, (struct sockaddr *) &rsin, sizeof(struct sockaddr_in));

	/*
	 * Set socket TTL - Be warned - I DoSed a Cisco 5500 RSM by sending
	 * a 60MBit/s stream in 14 Groups all with TTL of 1 and the switch
	 * went to lala land. It seems dropping MCAST traffic is very expensive
	 * in IOS 12.1 and its even dropped in Layer 3 instead of Layer 2 although
	 * nobody expects ICMP "TTL expired" for MCAST traffic
	 *
	 */
	if (s->ttl) {
		setsockopt(s->sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &s->ttl, sizeof(s->ttl));
	}

	/* We do want to get TSP packets */
	s->receiver=1;

	return 1;
}

void stream_send_udp(struct stream_s *s, uint8_t *tsp) {
	int	len;

	/* Copy TS packet to packet buffer */
	memcpy(&s->buffer[s->buffervalid], tsp, TS_PACKET_SIZE);
	s->buffervalid+=TS_PACKET_SIZE;

	/* check whether another packet would fit ? */
	if (s->buffervalid + TS_PACKET_SIZE > SOUT_UDP_PAYLOAD_MAX) {
		/* Send packet and reset valid counter */
		len=send(s->sockfd, s->buffer, s->buffervalid, MSG_DONTWAIT);

		if (len != s->buffervalid)
			logwrite(LOG_DEBUG, "streamudp: send didnt send all... %d/%d\n",
					len, s->buffervalid);

		s->buffervalid=0;
	}
}