/* RTMP - Socket Server $ID: $ */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include "rtmp.h" myConnections_t *connections = 0x0; int listenerFD = 0x0; int highSock = 0x0; int sStartListener() { int optVal = 0x1; struct sockaddr_in myAddr; // my address information if ((listenerFD = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if (setsockopt(listenerFD, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } myAddr.sin_family = AF_INET; // host byte order myAddr.sin_port = htons(MYPORT); // short, network byte order myAddr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP memset(myAddr.sin_zero, '\0', sizeof myAddr.sin_zero); if (bind(listenerFD, (struct sockaddr *)&myAddr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } if (listen(listenerFD, BACKLOG) == -1) { perror("listen"); exit(1); } fcntl(listenerFD, F_SETFL, fcntl(listenerFD, F_GETFL, 0) | O_NONBLOCK); highSock = listenerFD; return(0x0); } ssize_t sReadSocket(int socketFD,void *buffer,size_t length) { ssize_t recLen = 0x0; ssize_t recLen2 = 0x0; fd_set readset; FD_ZERO(&readset); FD_SET(socketFD,&readset); while (select(socketFD + 1,&readset,0x0,0x0,0x0)) { if (FD_ISSET(socketFD,&readset)) break; } recLen = read(socketFD,buffer,length); if (recLen < length) { while (select(socketFD + 1,&readset,0x0,0x0,0x0)) { if (FD_ISSET(socketFD,&readset)) break; } recLen2 = read(socketFD,buffer + (recLen -1),(length - recLen)); recLen += recLen2; } return(recLen); } int sGetConnection() { int newFD = 0x0; // New Socket; socklen_t sin_size; struct sockaddr_in remoteAddr; sin_size = sizeof(struct sockaddr_in); if ((newFD = accept(listenerFD, (struct sockaddr *)&remoteAddr, &sin_size)) == -1) { perror("accept"); } printf("Server: New connection from: %s\n",inet_ntoa(remoteAddr.sin_addr)); if (amfDoHandshake(newFD) == -1) { printf("Error: Bad Handshake\n"); // sRemoveConnection(newFD); close(newFD); } else { sAddConnection(newFD); highSock = newFD; } /* Return */ return(0x0); } int sAddConnection(int socketFD) { myConnections_t *tmpConnection = 0x0; printf("Adding Socket\n"); if (connections == 0x0) { connections = (myConnections_t *)malloc(sizeof(myConnections_t)); connections->prev = 0x0; connections->next = 0x0; connections->socketFD = socketFD; } else { tmpConnection = (myConnections_t *)malloc(sizeof(myConnections_t)); tmpConnection->socketFD = socketFD; tmpConnection->prev = 0x0; tmpConnection->next = connections; connections->prev = tmpConnection; connections = tmpConnection; } printf("Socket Added\n"); return(0x0); } int sRemoveConnection(int socketFD) { myConnections_t *tmpConnection = 0x0; printf("Removing Socket\n"); for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { if (tmpConnection->socketFD == socketFD) { if (tmpConnection == connections) { connections = tmpConnection->next; free(tmpConnection); } else { if (tmpConnection->prev != 0x0) tmpConnection->prev->next = tmpConnection->next; if (tmpConnection->next != 0x0) tmpConnection->next->prev = tmpConnection->prev; free(tmpConnection); } return(0x0); } } printf("Socket Removed\n"); return(-1); } int sGetConnections(fd_set *readset) { int retVal = 0; myConnections_t *tmpConnection = 0x0; FD_ZERO(readset); FD_SET(listenerFD,readset); if (connections != 0x0) { for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { FD_SET(tmpConnection->socketFD,readset); } retVal = 1; } return(retVal); } int sProcessConnections(fd_set *readset) { myConnections_t *tmpConnection = 0x0; if (FD_ISSET(listenerFD,readset)) sGetConnection(); for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { if (FD_ISSET(tmpConnection->socketFD,readset)) amfGetData(tmpConnection->socketFD); } return(0x0); }