9 Bounce* application = new Bounce();
15 act.sa_handler = SIG_IGN;
17 sigemptyset(&act.sa_mask);
18 sigaction(SIGPIPE, &act, 0);
21 * Create new application object, bind listeners and begin
24 application->bindListeners();
27 application->checkSockets();
31 void Bounce::bindListeners() {
43 if(!(configFd = fopen("bounce.conf", "r")))
45 printf("Error, unable to open config.\n");
49 while (fgets(tempBuf, 256, configFd) != NULL) {
50 if((tempBuf[0] != '#') && (tempBuf[0] != '\r')) {
53 case 'P': { /* Add new port listener */
55 vHost = strtok(NULL, ":");
56 localPort = atoi(strtok(NULL, ":"));
57 remoteServer = strtok(NULL, ":");
58 remotePort = atoi(strtok(NULL, ":"));
60 Listener* newListener = new Listener();
61 strcpy(newListener->myVhost, vHost);
62 strcpy(newListener->remoteServer, remoteServer);
63 newListener->remotePort = remotePort;
64 newListener->localPort = localPort;
65 printf("Adding new Listener: Local: %s:%i, Remote: %s:%i\n", vHost, localPort, remoteServer, remotePort);
67 newListener->beginListening();
68 listenerList.insert(listenerList.begin(), newListener);
76 void Bounce::checkSockets() {
78 * Build up a Select FD set, and Select() 'em.
80 typedef std::list<Listener*> listenerContainer;
81 typedef listenerContainer::iterator listIter;
83 typedef std::list<Connection*> connectionContainer;
84 typedef connectionContainer::iterator connIter;
98 listIter a = listenerList.begin();
99 while(a != listenerList.end())
102 FD_SET(tempFd, &readfds);
103 if (highestFd < tempFd) highestFd = tempFd;
107 connIter b = connectionsList.begin();
108 while(b != connectionsList.end())
110 tempFd = (*b)->localSocket->fd;
111 tempFd2 = (*b)->remoteSocket->fd;
112 FD_SET(tempFd, &readfds);
113 if (highestFd < tempFd) highestFd = tempFd;
114 FD_SET(tempFd2, &readfds);
115 if (highestFd < tempFd2) highestFd = tempFd2;
119 select(highestFd+1, &readfds, NULL, NULL, &tv);
122 * Check all connections for reading/writing
123 * First check Local FD's.
125 b = connectionsList.begin();
126 while(b != connectionsList.end())
128 tempFd = (*b)->localSocket->fd;
130 if (FD_ISSET(tempFd, &readfds))
132 tempBuf = (*b)->localSocket->read();
133 if ((tempBuf[0] == 0)) // Connection closed on one of our sockets.
135 close((*b)->localSocket->fd);
136 close((*b)->remoteSocket->fd);
137 printf("Closing FD: %i\n", (*b)->localSocket->fd);
138 printf("Closing FD: %i\n", (*b)->remoteSocket->fd);
141 b = connectionsList.erase(b);
143 (*b)->remoteSocket->write(tempBuf, (*b)->localSocket->lastReadSize);
152 * Now check Remote FD's..
154 b = connectionsList.begin();
155 while(b != connectionsList.end())
157 tempFd = (*b)->remoteSocket->fd;
158 if (FD_ISSET(tempFd, &readfds))
160 tempBuf = (*b)->remoteSocket->read();
161 if ((tempBuf[0] == 0)) // Connection closed on one of our sockets.
163 close((*b)->localSocket->fd);
164 close((*b)->remoteSocket->fd);
165 printf("Closing FD: %i\n", (*b)->localSocket->fd);
166 printf("Closing FD: %i\n", (*b)->remoteSocket->fd);
169 b = connectionsList.erase(b);
171 (*b)->localSocket->write(tempBuf, (*b)->remoteSocket->lastReadSize);
179 * Check all listeners for new connections.
181 a = listenerList.begin();
182 while(a != listenerList.end())
185 if (FD_ISSET(tempFd, &readfds))
187 recieveNewConnection(*a);
194 void Bounce::recieveNewConnection(Listener* listener)
196 Connection* newConnection = new Connection();
197 newConnection->localSocket = listener->handleAccept();
199 Socket* remoteSocket = new Socket();
200 newConnection->remoteSocket = remoteSocket;
201 if(remoteSocket->connectTo(listener->remoteServer, listener->remotePort)) {
202 connectionsList.insert(connectionsList.begin(), newConnection);
204 newConnection->localSocket->write("Unable to connect to remote host..\n");
205 close(newConnection->localSocket->fd);
206 delete(newConnection);
207 delete(remoteSocket);
212 Socket* Listener::handleAccept() {
214 int sin_size = sizeof(struct sockaddr_in);
216 Socket* newSocket = new Socket();
217 new_fd = accept(fd, (struct sockaddr*)&newSocket->address, (socklen_t*)&sin_size);
218 newSocket->fd = new_fd;
222 void Listener::beginListening() {
223 struct sockaddr_in my_addr;
228 fd = socket(AF_INET, SOCK_STREAM, 0); /* Check for no FD's left?! */
230 my_addr.sin_family = AF_INET;
231 my_addr.sin_port = htons(localPort);
232 my_addr.sin_addr.s_addr = inet_addr(myVhost);
233 bzero(&(my_addr.sin_zero), 8);
235 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
237 bindRes = bind(fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
243 * If we can't bind a listening port, we might aswell drop out.
245 printf("Unable to bind to %s:%i!\n", myVhost, localPort);
255 int Socket::write(char *message, int len)
257 if (fd == -1) return 0;
259 int amount = ::write(fd, message, len);
260 printf("Wrote %i Bytes.\n", amount);
264 int Socket::write(char *message)
266 if (fd == -1) return 0;
268 int amount = ::write(fd, message, strlen(message));
269 printf("Wrote %i Bytes.\n", amount);
274 int Socket::connectTo(char *hostname, unsigned short portnum) {
277 if ((hp = gethostbyname(hostname)) == NULL) {
281 memset(&address,0,sizeof(address));
282 memcpy((char *)&address.sin_addr,hp->h_addr,hp->h_length);
283 address.sin_family= hp->h_addrtype;
284 address.sin_port= htons((u_short)portnum);
286 if ((fd = socket(hp->h_addrtype,SOCK_STREAM,0)) < 0)
289 if (connect(fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
300 static char buffer[4096];
302 amountRead = ::read(fd, &buffer, 4096);
304 if ((amountRead == -1)) buffer[0] = '\0';
305 buffer[amountRead] = '\0';
307 printf("Read %i Bytes.\n", amountRead);
308 /* Record this incase we're dealing with binary data with 0's in it. */
309 lastReadSize = amountRead;
310 return (char *)&buffer;