From 8cbaf09b4f2e8001206817ac446ccc431931f3f0 Mon Sep 17 00:00:00 2001 From: Ruslan Kuchumov Date: Sat, 26 Jul 2014 21:07:45 +0000 Subject: [PATCH] moved udp code to networking.c --- src/ccextractor.c | 6 +- src/ccextractor.h | 5 +- src/file_functions.c | 65 ++---------------- src/networking.c | 158 +++++++++++++++++++++++++++++++++++-------- src/networking.h | 8 ++- src/params.c | 24 ++----- src/params_dump.c | 8 +-- 7 files changed, 149 insertions(+), 125 deletions(-) diff --git a/src/ccextractor.c b/src/ccextractor.c index d0157fdd..a09c1978 100644 --- a/src/ccextractor.c +++ b/src/ccextractor.c @@ -175,7 +175,7 @@ void init_options (struct ccx_s_options *options) options->ts_datastreamtype = -1; // User WANTED stream type (i.e. use the stream that has this type) options->ts_forced_streamtype=CCX_STREAM_TYPE_UNKNOWNSTREAM; // User selected (forced) stream type /* Networking */ - options->udpaddr = 0; + options->udpaddr = NULL; options->udpport=0; // Non-zero => Listen for UDP packets on this port, no files. options->send_to_srv = 0; options->tcpport = NULL; @@ -225,10 +225,6 @@ unsigned hauppauge_warning_shown=0; // Did we detect a possible Hauppauge captur unsigned teletext_warning_shown=0; // Did we detect a possible PAL (with teletext subs) and told the user already? - -struct sockaddr_in servaddr, cliaddr; - - struct ccx_s_write wbout1, wbout2; // Output structures /* File handles */ diff --git a/src/ccextractor.h b/src/ccextractor.h index 5586770f..a3724c19 100644 --- a/src/ccextractor.h +++ b/src/ccextractor.h @@ -116,7 +116,7 @@ struct ccx_s_options // Options from user parameters int ts_datastreamtype ; // User WANTED stream type (i.e. use the stream that has this type) unsigned ts_forced_streamtype; // User selected (forced) stream type /* Networking */ - in_addr_t udpaddr; + char *udpaddr; unsigned udpport; // Non-zero => Listen for UDP packets on this port, no files. unsigned send_to_srv; char *tcpport; @@ -318,7 +318,6 @@ LLONG gettotalfilessize (void); void prepare_for_new_file (void); void close_input_file (void); int switch_to_next_file (LLONG bytesinbuffer); -int init_sockets (void); void return_to_buffer (unsigned char *buffer, unsigned int bytes); // timing.c @@ -434,8 +433,6 @@ extern int current_file; extern LLONG result; // Number of bytes read/skipped in last read operation -extern struct sockaddr_in servaddr, cliaddr; - extern int strangeheader; extern unsigned char startbytes[STARTBYTESLENGTH]; diff --git a/src/file_functions.c b/src/file_functions.c index 67780f2f..7b093115 100644 --- a/src/file_functions.c +++ b/src/file_functions.c @@ -88,26 +88,6 @@ void close_input_file (void) } } -int init_sockets (void) -{ - static int socket_inited=0; - if (!socket_inited) - { -#ifdef _WIN32 - WSADATA wsaData = {0}; - // Initialize Winsock - iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (iResult != 0) { - wprintf(L"WSAStartup failed: %d\n", iResult); - return 1; - } -#endif - socket_inited=1; - } - - return 0; -} - /* Close current file and open next one in list -if any- */ /* bytesinbuffer is the number of bytes read (in some buffer) that haven't been added to 'past' yet. We provide this number to switch_to_next_file() so a final sanity check @@ -143,42 +123,8 @@ int switch_to_next_file (LLONG bytesinbuffer) return 0; } - if (init_sockets()) - return 1; - infd=socket(AF_INET,SOCK_DGRAM,0); - if (IN_MULTICAST(ccx_options.udpaddr)) - { - int on = 1; - (void)setsockopt(infd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); - } - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr=htonl(IN_MULTICAST(ccx_options.udpaddr) ? ccx_options.udpaddr : INADDR_ANY); - servaddr.sin_port=htons(ccx_options.udpport); - if (bind(infd,(struct sockaddr *)&servaddr,sizeof(servaddr))) - { - fatal (EXIT_BUG_BUG, "bind() failed."); - } - if (IN_MULTICAST(ccx_options.udpaddr)) { - struct ip_mreq group; - group.imr_multiaddr.s_addr = htonl(ccx_options.udpaddr); - group.imr_interface.s_addr = htonl(INADDR_ANY); - if (setsockopt(infd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0) - { - fatal (EXIT_BUG_BUG, "cannot join multicast group."); - } - } - mprint ("\n\r-----------------------------------------------------------------\n"); - if (ccx_options.udpaddr == INADDR_ANY) - { - mprint ("\rReading from UDP socket %u\n",ccx_options.udpport); - } - else - { - struct in_addr in; - in.s_addr = htonl(ccx_options.udpaddr); - mprint ("\rReading from UDP socket %s:%u\n", inet_ntoa(in), ccx_options.udpport); - } + infd = start_upd_srv(ccx_options.udpaddr, ccx_options.udpport); return 1; } @@ -192,7 +138,7 @@ int switch_to_next_file (LLONG bytesinbuffer) return 0; } - infd = start_srv(ccx_options.tcpport, ccx_options.tcp_password); + infd = start_tcp_srv(ccx_options.tcpport, ccx_options.tcp_password); return 1; } @@ -430,11 +376,8 @@ LLONG buffered_read_opt (unsigned char *buffer, unsigned int bytes) if (ccx_options.input_source==CCX_DS_FILE || ccx_options.input_source==CCX_DS_STDIN) i=read (infd, filebuffer+keep,FILEBUFFERSIZE-keep); else - { - socklen_t len = sizeof(cliaddr); - i = recvfrom(infd,(char *) filebuffer+keep,FILEBUFFERSIZE-keep,0,(struct sockaddr *)&cliaddr,&len); - } - if( i == -1) + i = recvfrom(infd,(char *) filebuffer+keep,FILEBUFFERSIZE-keep,0,NULL,NULL); + if (i == -1) fatal (EXIT_READ_ERROR, "Error reading input stream!\n"); if (i==0) { diff --git a/src/networking.c b/src/networking.c index a41c93b1..7199f298 100644 --- a/src/networking.c +++ b/src/networking.c @@ -60,6 +60,8 @@ ssize_t writen(int fd, const void *vptr, size_t n); ssize_t write_byte(int fd, char status); ssize_t read_byte(int fd, char *status); +void init_sockets (void); + #if DEBUG_OUT void pr_command(char c); #endif @@ -75,7 +77,7 @@ void connect_to_srv(const char *addr, const char *port) if (NULL == port) port = DFT_PORT; - mprint("\n----------------------------------------------------------------------\n"); + mprint("\n\r----------------------------------------------------------------------\n"); mprint("Connecting to %s:%s\n", addr, port); if ((srv_sd = tcp_connect(addr, port)) < 0) @@ -87,7 +89,7 @@ void connect_to_srv(const char *addr, const char *port) mprint("Connected to %s:%s\n", addr, port); } -void net_send_header(const char *data, size_t len) +void net_send_header(const unsigned char *data, size_t len) { assert(srv_sd > 0); @@ -119,7 +121,7 @@ void net_send_header(const char *data, size_t len) } ssize_t rc; - if ((rc = writen(srv_sd, data, len)) != len) + if ((rc = writen(srv_sd, data, len)) != (int) len) { if (rc < 0) mprint("write() error: %s", strerror(errno)); @@ -127,7 +129,7 @@ void net_send_header(const char *data, size_t len) } } -void net_send_cc(const char *data, size_t len) +void net_send_cc(const unsigned char *data, size_t len) { assert(srv_sd > 0); @@ -136,7 +138,7 @@ void net_send_cc(const char *data, size_t len) #endif ssize_t rc; - if ((rc = writen(srv_sd, data, len)) != len) + if ((rc = writen(srv_sd, data, len)) != (int) len) { if (rc < 0) mprint("write() error: %s", strerror(errno)); @@ -174,7 +176,7 @@ ssize_t write_block(int fd, char command, const char *buf, size_t buf_len) #endif char len_str[INT_LEN] = {0}; - snprintf(len_str, INT_LEN, "%u", buf_len); + snprintf(len_str, INT_LEN, "%zu", buf_len); if ((rc = writen(fd, len_str, INT_LEN)) < 0) return -1; else if (rc != INT_LEN) @@ -228,15 +230,7 @@ int tcp_connect(const char *host, const char *port) assert(host != NULL); assert(port != NULL); -#ifdef _WIN32 - WSADATA wsaData = { 0 }; - // Initialize Winsock - int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (iResult != 0) { - wprintf(L"WSAStartup failed: %d\n", iResult); - return 1; - } -#endif + init_sockets(); struct addrinfo hints; memset(&hints, 0, sizeof(struct addrinfo)); @@ -298,7 +292,6 @@ int ask_passwd(int sd) { assert(sd >= 0); - int rc; size_t len; char pw[BUFFER_SIZE] = { 0 }; @@ -338,7 +331,7 @@ int ask_passwd(int sd) fflush(stdout); char *p = pw; - while (p - pw < sizeof(pw) && ((*p = fgetc(stdin)) != '\n')) + while ((unsigned)(p - pw) < sizeof(pw) && ((*p = fgetc(stdin)) != '\n')) p++; len = p - pw; /* without \n */ @@ -372,12 +365,12 @@ int ask_passwd(int sd) return 1; } -int start_srv(const char *port, const char *pwd) +int start_tcp_srv(const char *port, const char *pwd) { if (NULL == port) port = DFT_PORT; - mprint("\n----------------------------------------------------------------------\n"); + mprint("\n\r----------------------------------------------------------------------\n"); mprint("Binding to %s\n", port); int fam; @@ -521,15 +514,7 @@ int check_password(int fd, const char *pwd) int tcp_bind(const char *port, int *family) { -#ifdef _WIN32 - WSADATA wsaData = { 0 }; - // Initialize Winsock - int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (iResult != 0) { - wprintf(L"WSAStartup failed: %d\n", iResult); - return 1; - } -#endif + init_sockets(); struct addrinfo hints; memset(&hints, 0, sizeof(struct addrinfo)); @@ -846,3 +831,120 @@ ssize_t read_byte(int fd, char *ch) return readn(fd, ch, 1); } + +int start_upd_srv(const char *addr_str, unsigned port) +{ + init_sockets(); + + in_addr_t addr; + if (addr_str != NULL) + { + struct hostent *host = gethostbyname(addr_str); + if (NULL == host) + { + fatal(EXIT_MALFORMED_PARAMETER, "Cannot look up udp network address: %s\n", + addr_str); + } + else if (host->h_addrtype != AF_INET) + { + fatal(EXIT_MALFORMED_PARAMETER, "No support for non-IPv4 network addresses: %s\n", + addr_str); + } + + addr = ntohl(((struct in_addr *)host->h_addr_list[0])->s_addr); + } + else + { + addr = INADDR_ANY; + } + + int sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (-1 == sockfd) { +#if _WIN32 + wprintf(L"socket() eror: %ld\n", WSAGetLastError()); + exit(EXIT_FAILURE); +#else + mprint("socket() error: %s\n", strerror(errno)); +#endif + } + + if (IN_MULTICAST(addr)) + { + int on = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) + { +#if _WIN32 + wprintf(L"setsockopt() error: %ld\n", WSAGetLastError()); +#else + mprint("setsockopt() error: %s\n", strerror(errno)); +#endif + } + } + + struct sockaddr_in servaddr; + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = addr; + servaddr.sin_port = htons(port); + if (IN_MULTICAST(addr)) + servaddr.sin_addr.s_addr = addr; + else + servaddr.sin_addr.s_addr = INADDR_ANY; + + if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) + { +#if _WIN32 + wprintf(L"bind() eror: %ld\n", WSAGetLastError()); + exit(EXIT_FAILURE); +#else + fatal(EXIT_BUG_BUG, "bind() error: %s\n", strerror(errno)); +#endif + } + + if (IN_MULTICAST(addr)) { + struct ip_mreq group; + group.imr_multiaddr.s_addr = htonl(addr); + group.imr_interface.s_addr = htonl(INADDR_ANY); + if (setsockopt(infd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0) + { +#if _WIN32 + wprintf(L"setsockopt() error: %ld\n", WSAGetLastError()); +#else + mprint("setsockopt() error: %s\n", strerror(errno)); +#endif + fatal(EXIT_BUG_BUG, "Cannot join multicast group."); + } + } + + mprint("\n\r----------------------------------------------------------------------\n"); + if (addr == INADDR_ANY) + { + mprint("\rReading from UDP socket %u\n", port); + } + else + { + struct in_addr in; + in.s_addr = htonl(addr); + mprint("\rReading from UDP socket %s:%u\n", inet_ntoa(in), port); + } + + return sockfd; +} + +void init_sockets (void) +{ + static int socket_inited = 0; + if (!socket_inited) + { + // Initialize Winsock +#ifdef _WIN32 + WSADATA wsaData = {0}; + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + { + wprintf(L"WSAStartup failed: %d\n", iResult); + exit(EXIT_FAILURE); + } +#endif + + socket_inited = 1; + } +} diff --git a/src/networking.h b/src/networking.h index 28fab0a9..b013e411 100644 --- a/src/networking.h +++ b/src/networking.h @@ -5,9 +5,11 @@ void connect_to_srv(const char *addr, const char *port); -void net_send_header(const char *data, size_t len); -void net_send_cc(const char *data, size_t len); +void net_send_header(const unsigned char *data, size_t len); +void net_send_cc(const unsigned char *data, size_t len); -int start_srv(const char *port, const char *pwd); +int start_tcp_srv(const char *port, const char *pwd); + +int start_upd_srv(const char *addr, unsigned port); #endif /* end of include guard: NETWORKING_H */ diff --git a/src/params.c b/src/params.c index 6b1682c7..085d9a7f 100644 --- a/src/params.c +++ b/src/params.c @@ -1548,33 +1548,19 @@ void parse_parameters (int argc, char *argv[]) /* Network stuff */ if (strcmp (argv[i],"-udp")==0 && ih_addrtype != AF_INET) - { - fatal(EXIT_MALFORMED_PARAMETER, "No support for non-IPv4 network addresses: %s\n", - argv[i+1]); - } - ccx_options.udpaddr = ntohl(((struct in_addr *)host->h_addr_list[0])->s_addr); + ccx_options.udpaddr = argv[i + 1]; ccx_options.udpport = atoi_hex(colon + 1); } else { - ccx_options.udpaddr = INADDR_ANY; - ccx_options.udpport = atoi_hex(argv[i+1]); + ccx_options.udpaddr = NULL; + ccx_options.udpport = atoi_hex(argv[i + 1]); } + ccx_options.input_source=CCX_DS_NETWORK; i++; continue; diff --git a/src/params_dump.c b/src/params_dump.c index b032abe4..0c986905 100644 --- a/src/params_dump.c +++ b/src/params_dump.c @@ -14,17 +14,15 @@ void params_dump(void) mprint ("stdin"); break; case CCX_DS_NETWORK: - if (ccx_options.udpaddr == INADDR_ANY) + if (ccx_options.udpaddr == NULL) mprint ("Network, UDP/%u",ccx_options.udpport); else { - struct in_addr in; - in.s_addr = htonl(ccx_options.udpaddr); - mprint ("Network, %s:%d",inet_ntoa(in), ccx_options.udpport); + mprint ("Network, %s:%d",ccx_options.udpport, ccx_options.udpport); } break; case CCX_DS_TCP: - mprint("Network, TCP port: %s", ccx_options.tcpport); + mprint("Network, TCP/%s", ccx_options.tcpport); break; } mprint ("\n");