📄 alc_socket.c
字号:
/* $Author: peltotal $ $Date: 2006/02/17 09:14:36 $ $Revision: 1.30 $ *//* * MAD-ALCLIB: Implementation of ALC/LCT protocols, Compact No-Code FEC, * Simple XOR FEC, Reed-Solomon FEC, and RLC Congestion Control protocol. * Copyright (c) 2003-2006 TUT - Tampere University of Technology * main authors/contacts: jani.peltotalo@tut.fi and sami.peltotalo@tut.fi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "inc.h"/* * This function creates and initializes tx or rx socket * * Params: alc_channel_t *ch: Pointer to channel * * Return: int: 0 in success, -1 otherwise * */int init_alc_socket(alc_channel_t *ch) { int receiver_socket_buffer_size = RECEIVER_SOCKET_BUFFER_SIZE; int ttl; int loop; int reuse; int mode; int addr_type; struct addrinfo hints, *local; struct in_addr if_addr; /* interface IP address for IPv4 multicast */ #if defined(LINUX) && defined(SSM) struct sockaddr_in6 source;#endif local = NULL; mode = ch->s->mode; addr_type = ch->s->addr_type; if(mode == SENDER) { if((ch->tx_sock = socket(ch->s->addr_family, SOCK_DGRAM, 0)) < 0) { #ifdef WIN32 printf("socket failed with: %d\n", WSAGetLastError()); fflush(stdout);#else printf("socket failed: %d\n", errno); fflush(stdout);#endif return -1; } memset(&hints, 0, sizeof(hints)); hints.ai_family = ch->s->addr_family; hints.ai_socktype = SOCK_DGRAM; /* ch->addrinfo is used in sendto function */ if(getaddrinfo(ch->addr, ch->port, &hints, &ch->addrinfo) != 0) {#ifdef WIN32 printf("getaddrinfo failed: %d\n", WSAGetLastError()); fflush(stdout); closesocket(ch->tx_sock);#else printf("getaddrinfo failed: %d\n", errno); fflush(stdout); close(ch->tx_sock);#endif return -1; } /* Bind the socket to right interface */ if(ch->intface != NULL) { if((((ch->s->addr_family == PF_INET6)) || (addr_type == 1))) { if(getaddrinfo(ch->intface, 0, &hints, &local) != 0) {#ifdef WIN32 printf("getaddrinfo failed: %d\n", WSAGetLastError()); closesocket(ch->tx_sock);#else printf("getaddrinfo failed: %d\n", errno); close(ch->tx_sock);#endif return -1; } if(bind(ch->tx_sock, local->ai_addr, local->ai_addrlen) < 0) {#ifdef WIN32 printf("bind failed: %d\n", WSAGetLastError()); closesocket(ch->tx_sock);#else printf("bind failed: %d\n", errno); close(ch->tx_sock);#endif return -1; } } else if(((ch->s->addr_family == PF_INET) && (addr_type == 0))) { /* does not work without this interface setting */ if_addr.s_addr = inet_addr(ch->intface); /* specify multicast interface */ if(setsockopt(ch->tx_sock, IPPROTO_IP, IP_MULTICAST_IF, (char*)&if_addr.s_addr, sizeof(if_addr.s_addr)) < 0 ) { #ifdef WIN32 printf("setsockopt (IP_MULTICAST_IF) failed: %d\n", WSAGetLastError()); closesocket(ch->tx_sock);#else printf("setsockopt (IP_MULTICAST_IF) failed: %d\n", errno); close(ch->tx_sock);#endif return -1; } } } if(addr_type == 0) { /* TTL */ ttl = min(ch->s->def_ttl, 255); if(ch->s->addr_family == PF_INET) { if(setsockopt(ch->tx_sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) < 0 ) {#ifdef WIN32 printf("setsockopt (IP_MULTICAST_TTL) failed: %d\n", WSAGetLastError()); closesocket(ch->tx_sock);#else printf("setsockopt (IP_MULTICAST_TTL) failed: %d\n", errno); close(ch->tx_sock);#endif /* WIN32 */ return -1; } } else if(ch->s->addr_family == PF_INET6) { if(setsockopt(ch->tx_sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl, sizeof(ttl)) < 0 ) {#ifdef WIN32 printf("setsockopt (IPV6_MULTICAST_HOPS) failed: %d\n", WSAGetLastError()); closesocket(ch->tx_sock);#else printf("setsockopt (IPV6_MULTICAST_HOPS) failed: %d\n", errno); close(ch->tx_sock);#endif /* WIN32 */ return -1; } } /* Loopback (doesn't work in Windows, even if loop = 0, data is looped back) */ /* set to 0, when you don't have to do testing any more */ loop = 1; if(ch->s->addr_family == PF_INET) { if(setsockopt(ch->tx_sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loop, sizeof(loop)) != 0) {#ifdef WIN32 printf("setsockopt (IP_MULTICAST_LOOP) failed: %d\n", WSAGetLastError()); closesocket(ch->tx_sock);#else printf("setsockopt (IP_MULTICAST_LOOP) failed: %d\n", errno); close(ch->tx_sock);#endif /* WIN32 */ return -1; } } else if(ch->s->addr_family == PF_INET6) { if(setsockopt(ch->tx_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&loop, sizeof(loop)) != 0) {#ifdef WIN32 printf("setsockopt (IPV6_MULTICAST_LOOP) failed: %d\n", WSAGetLastError()); closesocket(ch->tx_sock);#else printf("setsockopt (IPV6_MULTICAST_LOOP) failed: %d\n", errno); close(ch->tx_sock);#endif /* WIN32 */ return -1; } } } if(local != NULL) { freeaddrinfo(local); } } if(mode == RECEIVER) { if((ch->rx_sock = socket(ch->s->addr_family, SOCK_DGRAM, 0)) < 0) { #ifdef WIN32 printf("socket failed with: %d\n", WSAGetLastError()); fflush(stdout);#else printf("socket failed: %d\n", errno); fflush(stdout);#endif return -1; } memset(&hints, 0, sizeof(hints)); hints.ai_family = ch->s->addr_family; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; if(getaddrinfo(ch->intface, ch->port, &hints, &ch->addrinfo) != 0) {#ifdef WIN32 printf("getaddrinfo failed: %d\n", WSAGetLastError()); closesocket(ch->tx_sock);#else printf("getaddrinfo failed: %d\n", errno); close(ch->tx_sock);#endif return -1; } reuse = 1; if(setsockopt(ch->rx_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0 ) {#ifdef WIN32 printf("setsockopt (SO_REUSEADDR) failed: %d\n", WSAGetLastError()); closesocket(ch->rx_sock);#else printf("setsockopt (SO_REUSEADDR) failed: %d\n", errno); close(ch->rx_sock);#endif return -1; } if(setsockopt(ch->rx_sock, SOL_SOCKET, SO_RCVBUF, (char *)&receiver_socket_buffer_size, sizeof(int))) {#ifdef WIN32 printf("setsockopt (SO_RCVBUF) failed: %d\n", WSAGetLastError()); closesocket(ch->rx_sock);#else printf("setsockopt (SO_RCVBUF) failed: %d\n", errno); close(ch->rx_sock);#endif return -1; } if(bind(ch->rx_sock, ch->addrinfo->ai_addr, ch->addrinfo->ai_addrlen) < 0) {#ifdef WIN32 printf("bind failed: %d\n", WSAGetLastError()); closesocket(ch->rx_sock);#else printf("bind failed: %d\n", errno); close(ch->rx_sock);#endif return -1; } if(addr_type == 0) { if(ch->s->addr_family == PF_INET) { memset((void *)&ch->remote, 0, sizeof(ch->remote)); ch->remote.sin_addr.s_addr = inet_addr(ch->addr); ch->remote.sin_port = (unsigned short)atoi(ch->port); ch->remote.sin_family = ch->s->addr_family; } else if(ch->s->addr_family == PF_INET6) { memset((void *)&ch->remote6, 0, sizeof(ch->remote6));#ifdef WIN32 WSAStringToAddress(ch->addr, PF_INET6, NULL, (struct sockaddr*)&ch->remote6, &ch->addrinfo->ai_addrlen);#else inet_pton(PF_INET6, ch->addr, &ch->remote6.sin6_addr);#endif ch->remote6.sin6_port = (unsigned short)atoi(ch->port); ch->remote6.sin6_family = ch->s->addr_family; } } if(addr_type == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -