Added patch for rtp from ksolomko@sipwise.com
parent
7b78cc3bbf
commit
444393141b
@ -0,0 +1,194 @@
|
||||
--- a/send_packets.c
|
||||
+++ b/send_packets.c
|
||||
@@ -115,134 +115,109 @@
|
||||
struct timeval *, struct timeval *);
|
||||
void send_packets_cleanup(void *arg)
|
||||
{
|
||||
- int sock = (int) arg;
|
||||
+ int *sock = arg;
|
||||
|
||||
// Close send socket
|
||||
- close(sock);
|
||||
+ if (sock && *sock != -1)
|
||||
+ close(*sock);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
send_packets (play_args_t * play_args)
|
||||
{
|
||||
- int ret, sock, port_diff;
|
||||
+ int ret, sock;
|
||||
pcap_pkt *pkt_index, *pkt_max;
|
||||
- uint16_t *from_port, *to_port;
|
||||
+ pcap_pkts *pkts = play_args->pcap;
|
||||
struct timeval didsleep = { 0, 0 };
|
||||
struct timeval start = { 0, 0 };
|
||||
struct timeval last = { 0, 0 };
|
||||
- pcap_pkts *pkts = play_args->pcap;
|
||||
- /* to and from are pointers in case play_args (call sticky) gets modified! */
|
||||
- struct sockaddr_storage *to = &(play_args->to);
|
||||
- struct sockaddr_storage *from = &(play_args->from);
|
||||
- struct udphdr *udp;
|
||||
- struct sockaddr_in6 to6, from6;
|
||||
+ /* to and from are pointers in case play_args (call sticky) gets modified! */
|
||||
char buffer[PCAP_MAXPACKET];
|
||||
- int temp_sum;
|
||||
+ struct udphdr * udp = (struct udphdr *) buffer;
|
||||
+ struct sockaddr_in * to = (struct sockaddr_in *) &play_args->to;
|
||||
+ struct sockaddr_in6 * to6 = (struct sockaddr_in6 *) &play_args->to;
|
||||
+ uint16_t port_diff = 0;
|
||||
|
||||
#ifndef MSG_DONTWAIT
|
||||
int fd_flags;
|
||||
+ fd_flags = fcntl(sock, F_GETFL , NULL);
|
||||
+ fd_flags |= O_NONBLOCK;
|
||||
+ fcntl(sock, F_SETFL , fd_flags);
|
||||
#endif
|
||||
|
||||
if (media_ip_is_ipv6) {
|
||||
- sock = socket(PF_INET6, SOCK_RAW, IPPROTO_UDP);
|
||||
- if (sock < 0) {
|
||||
- ERROR("Can't create raw socket (need to run as root?)");
|
||||
- }
|
||||
- from_port = &(((struct sockaddr_in6 *)(void *) from )->sin6_port);
|
||||
- to_port = &(((struct sockaddr_in6 *)(void *) to )->sin6_port);
|
||||
+ sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
+ } else {
|
||||
+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
}
|
||||
- else {
|
||||
- sock = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);
|
||||
- if (sock < 0) {
|
||||
- ERROR("Can't create raw socket (need to run as root?)");
|
||||
- }
|
||||
- from_port = &(((struct sockaddr_in *)(void *) from )->sin_port);
|
||||
- to_port = &(((struct sockaddr_in *)(void *) to )->sin_port);
|
||||
+ if (sock < 0) {
|
||||
+ ERROR("Cannot create udp socket (need to run as root?)");
|
||||
}
|
||||
-
|
||||
-#ifndef MSG_DONTWAIT
|
||||
- fd_flags = fcntl(sock, F_GETFL , NULL);
|
||||
- fd_flags |= O_NONBLOCK;
|
||||
- fcntl(sock, F_SETFL , fd_flags);
|
||||
-#endif
|
||||
- udp = (struct udphdr *)buffer;
|
||||
|
||||
pkt_index = pkts->pkts;
|
||||
pkt_max = pkts->max;
|
||||
-
|
||||
+
|
||||
if (media_ip_is_ipv6) {
|
||||
- memset(&to6, 0, sizeof(to6));
|
||||
- memset(&from6, 0, sizeof(from6));
|
||||
- to6.sin6_family = AF_INET6;
|
||||
- from6.sin6_family = AF_INET6;
|
||||
- memcpy(&(to6.sin6_addr.s6_addr), &(((struct sockaddr_in6 *)(void *) to)->sin6_addr.s6_addr), sizeof(to6.sin6_addr.s6_addr));
|
||||
- memcpy(&(from6.sin6_addr.s6_addr), &(((struct sockaddr_in6 *)(void *) from)->sin6_addr.s6_addr), sizeof(from6.sin6_addr.s6_addr));
|
||||
+ memset(to6, 0, sizeof(*to6));
|
||||
+ to6->sin6_family = AF_INET6;
|
||||
+ memcpy(to6->sin6_addr.s6_addr,
|
||||
+ &(((struct sockaddr_in6 *)&play_args->to)->sin6_addr.s6_addr),
|
||||
+ sizeof(to6->sin6_addr.s6_addr));
|
||||
+ to6->sin6_port = htons(to->sin_port);
|
||||
}
|
||||
-
|
||||
|
||||
/* Ensure the sender socket is closed when the thread exits - this
|
||||
* allows the thread to be cancelled cleanly.
|
||||
*/
|
||||
- pthread_cleanup_push(send_packets_cleanup, ((void *) sock));
|
||||
+ pthread_cleanup_push(send_packets_cleanup, &sock);
|
||||
|
||||
+ // modify UDP ports
|
||||
+ pcap_pkt * pkt_index = play_args->pcap->pkts;
|
||||
+ memcpy(udp, pkt_index->data, sizeof(*udp));
|
||||
+ port_diff = ntohs (udp->uh_dport) - pkts->base;
|
||||
+ if (media_ip_is_ipv6) {
|
||||
+ to6->sin6_port = htons(port_diff + to->sin_port);
|
||||
+ } else {
|
||||
+ to->sin_port = htons(port_diff + to->sin_port);
|
||||
+ }
|
||||
|
||||
while (pkt_index < pkt_max) {
|
||||
- memcpy(udp, pkt_index->data, pkt_index->pktlen);
|
||||
- port_diff = ntohs (udp->uh_dport) - pkts->base;
|
||||
- // modify UDP ports
|
||||
- udp->uh_sport = htons(port_diff + *from_port);
|
||||
- udp->uh_dport = htons(port_diff + *to_port);
|
||||
-
|
||||
- if (!media_ip_is_ipv6) {
|
||||
- temp_sum = checksum_carry(pkt_index->partial_check + check((u_int16_t *) &(((struct sockaddr_in *)(void *) from)->sin_addr.s_addr), 4) + check((u_int16_t *) &(((struct sockaddr_in *)(void *) to)->sin_addr.s_addr), 4) + check((u_int16_t *) &udp->uh_sport, 4));
|
||||
- }
|
||||
- else {
|
||||
- temp_sum = checksum_carry(pkt_index->partial_check + check((u_int16_t *) &(from6.sin6_addr.s6_addr), 16) + check((u_int16_t *) &(to6.sin6_addr.s6_addr), 16) + check((u_int16_t *) &udp->uh_sport, 4));
|
||||
- }
|
||||
-
|
||||
-#ifndef _HPUX_LI
|
||||
-#ifdef __HPUX
|
||||
- udp->uh_sum = (temp_sum>>16)+((temp_sum & 0xffff)<<16);
|
||||
-#else
|
||||
- udp->uh_sum = temp_sum;
|
||||
-#endif
|
||||
-#else
|
||||
- udp->uh_sum = temp_sum;
|
||||
-#endif
|
||||
-
|
||||
- do_sleep ((struct timeval *) &pkt_index->ts, &last, &didsleep,
|
||||
- &start);
|
||||
+ do_sleep ((struct timeval *) &pkt_index->ts, &last, &didsleep, &start);
|
||||
#ifdef MSG_DONTWAIT
|
||||
- if (!media_ip_is_ipv6) {
|
||||
- ret = sendto(sock, buffer, pkt_index->pktlen, MSG_DONTWAIT,
|
||||
- (struct sockaddr *)(void *) to, sizeof(struct sockaddr_in));
|
||||
- }
|
||||
- else {
|
||||
- ret = sendto(sock, buffer, pkt_index->pktlen, MSG_DONTWAIT,
|
||||
- (struct sockaddr *)(void *) &to6, sizeof(struct sockaddr_in6));
|
||||
+ u_int pd_offset = sizeof(*udp);
|
||||
+ u_char * rtp_data = (u_char *) calloc(pkt_index->pktlen - pd_offset, 1);
|
||||
+ memcpy(rtp_data, pkt_index->data + pd_offset, pkt_index->pktlen);
|
||||
+ if (media_ip_is_ipv6) {
|
||||
+ ret = sendto(sock, rtp_data, pkt_index->pktlen - pd_offset, MSG_DONTWAIT,
|
||||
+ (struct sockaddr *) to6, sizeof(*to6));
|
||||
+ } else {
|
||||
+ ret = sendto(sock, rtp_data, pkt_index->pktlen - pd_offset, MSG_DONTWAIT,
|
||||
+ (struct sockaddr *) to, sizeof(*to));
|
||||
}
|
||||
#else
|
||||
- if (!media_ip_is_ipv6) {
|
||||
- ret = sendto(sock, buffer, pkt_index->pktlen, 0,
|
||||
- (struct sockaddr *)(void *) to, sizeof(struct sockaddr_in));
|
||||
- }
|
||||
- else {
|
||||
- ret = sendto(sock, buffer, pkt_index->pktlen, 0,
|
||||
- (struct sockaddr *)(void *) &to6, sizeof(struct sockaddr_in6));
|
||||
+ if (media_ip_is_ipv6) {
|
||||
+ ret = sendto(sock, rtp_data, pkt_index->pktlen - pd_offset, 0,
|
||||
+ (struct sockaddr *) to6, sizeof(*to6));
|
||||
+ } else {
|
||||
+ ret = sendto(sock, rtp_data, pkt_index->pktlen - pd_offset, 0,
|
||||
+ (struct sockaddr *) to, sizeof(*to));
|
||||
}
|
||||
#endif
|
||||
+
|
||||
+ free(rtp_data);
|
||||
+
|
||||
if (ret < 0) {
|
||||
close(sock);
|
||||
WARNING("send_packets.c: sendto failed with error: %s", strerror(errno));
|
||||
return( -1);
|
||||
}
|
||||
|
||||
- rtp_pckts_pcap++;
|
||||
- rtp_bytes_pcap += pkt_index->pktlen - sizeof(*udp);
|
||||
+ rtp_pckts_pcap++;
|
||||
+ rtp_bytes_pcap += pkt_index->pktlen - pd_offset;
|
||||
memcpy (&last, &(pkt_index->ts), sizeof (struct timeval));
|
||||
pkt_index++;
|
||||
- }
|
||||
+ }
|
||||
|
||||
/* Closing the socket is handled by pthread_cleanup_push()/pthread_cleanup_pop() */
|
||||
pthread_cleanup_pop(1);
|
Loading…
Reference in new issue