// FDSET List
fd_set readfds;
+
+#ifdef SUPPORT_IPV4
+ struct sockaddr_in serverAddrV4;
+ size_t serverAddrV4len;
+#endif
+#ifdef SUPPORT_IPV6
+ struct sockaddr_in6 serverAddrV6;
+ size_t serverAddrV6len;
+#endif
+
int main() {
int opt = 1;
SOCKET serverSocketV4 = 0;
// Setup structs
#ifdef SUPPORT_IPV4
- struct sockaddr_in serverAddrV4;
memset(&serverAddrV4, 0, sizeof(struct sockaddr_in));
serverAddrV4.sin_addr.s_addr = INADDR_ANY;
serverAddrV4.sin_port = htons(LISTENING_PORT);
serverAddrV4.sin_family = AF_INET;
- size_t serverAddrV4len = sizeof(serverAddrV4);
+ serverAddrV4len = sizeof(serverAddrV4);
#endif
#ifdef SUPPORT_IPV6
- struct sockaddr_in6 serverAddrV6;
memset(&serverAddrV6, 0, sizeof(struct sockaddr_in6));
serverAddrV6.sin6_addr = in6addr_any;
serverAddrV6.sin6_flowinfo = 0;
serverAddrV6.sin6_port = htons(LISTENING_PORT);
serverAddrV6.sin6_family = AF_INET6;
- size_t serverAddrV6len = sizeof(serverAddrV6);
+ serverAddrV6len = sizeof(serverAddrV6);
#endif
#ifdef SUPPORT_IPV4
// Create socket
clients[i] = allocClient();
clients[i]->FD = newSocket;
clients[i]->type = 4;
+ clients[i]->bufCap = sizeof(clients[i]->buf);
// Set nonblock
net_nonblock(clients[i]->FD);
break;
clients[i] = allocClient();
clients[i]->FD = newSocket;
clients[i]->type = 6;
+ clients[i]->bufCap = sizeof(clients[i]->buf);
// Set nonblock
net_nonblock(clients[i]->FD);
break;
if(clients[i] == 0) continue;
SD = clients[i]->FD;
if(FD_ISSET(SD, &readfds)) {
- //bytesRead = read(SD, buffer, sizeof(buffer));
- bytesRead = recv_log(SD,buffer,sizeof(buffer), 0);
-
- if(bytesRead == -1) {
- if(net_wouldblock()) {
- goto endOfLoop;
- }
- net_perror("RECV");
- }
-
- // Disconnect
- if(bytesRead == 0) {
-#ifdef SUPPORT_IPV4
- if(clients[i]->type == 4) {
- getpeername(SD,(struct sockaddr*)&serverAddrV4,(socklen_t*)&serverAddrV4len);
- inet_ntop(AF_INET, &(serverAddrV4.sin_addr), client_addr, sizeof(client_addr));
- printf("Client disconnected from Socket: %"PRISocket", IP: %s PORT: %d\n", SD, client_addr, ntohs(serverAddrV4.sin_port));
- fflush(stdout);
- }
-#endif
-#ifdef SUPPORT_IPV6
- if(clients[i]->type == 6) {
- getpeername(SD,(struct sockaddr*)&serverAddrV6,(socklen_t*)&serverAddrV6len);
- inet_ntop(AF_INET6, &(serverAddrV6.sin6_addr), client_addr, sizeof(client_addr));
- printf("Client disconnected from Socket: %"PRISocket", IP: %s PORT: %d\n", SD, client_addr, ntohs(serverAddrV6.sin6_port));
- fflush(stdout);
- }
-#endif
- killConnection(clients[i]);
- } else {
- // Add null byte
- buffer[bytesRead] = '\0';
-
- int j;
- char *buffer2 = buffer;
- char tmp;
- for(j=0;j<bytesRead;j++){
- if(buffer[j] == '\n'){
- char tmp = buffer[j+1];
- buffer[j+1] = 0;
- //Send to processing
- processPacket(clients[i], buffer2, strlen(buffer2));
- buffer[j+1] = tmp;
- buffer2 = &(buffer[j+1]);
- }
- }
- }
- endOfLoop:;
+ recvProc(clients[i]);
}
}
}
#include "net.h"
+#include "irc.h"
void sendall_log(SOCKET socket, const char *buffer, size_t length, int flags) {
int i;
return NewClient;
};
-void killConnection(struct client_data *client) {
+void killConnection(struct client_data *cl) {
int i;
+ char client_addr[100];
+ if(cl == 0) return;
+#ifdef SUPPORT_IPV4
+ if(cl->type == 4) {
+ getpeername(cl->FD,(struct sockaddr*)&serverAddrV4,(socklen_t*)&serverAddrV4len);
+ inet_ntop(AF_INET, &(serverAddrV4.sin_addr), client_addr, sizeof(client_addr));
+ printf("Client disconnected from Socket: %"PRISocket", IP: %s PORT: %d\n", cl->FD, client_addr, ntohs(serverAddrV4.sin_port));
+ fflush(stdout);
+ }
+#endif
+#ifdef SUPPORT_IPV6
+ if(cl->type == 6) {
+ getpeername(cl->FD,(struct sockaddr*)&serverAddrV6,(socklen_t*)&serverAddrV6len);
+ inet_ntop(AF_INET6, &(serverAddrV6.sin6_addr), client_addr, sizeof(client_addr));
+ printf("Client disconnected from Socket: %"PRISocket", IP: %s PORT: %d\n", cl->FD, client_addr, ntohs(serverAddrV6.sin6_port));
+ fflush(stdout);
+ }
+#endif
for(i=0;i<CLIENTS;i++) {
- if(clients[i] == client) {
+ if(clients[i] == cl) {
clients[i] = 0;
}
}
- closesocket(client->FD);
- free(client);
+ closesocket(cl->FD);
+ free(cl);
+}
+
+void recvProc(struct client_data *cl) {
+ ssize_t bytesRead;
+ char *x;
+ char tmp;
+ while(1){
+ // I hate you
+ if(cl->bufLen == cl->bufCap) killConnection(cl);
+ bytesRead = recv_log(cl->FD,cl->buf + cl->bufLen,cl->bufCap - cl->bufLen, 0);
+ switch(bytesRead){
+ // Disconnect
+ case 0:
+ killConnection(cl);
+ return;
+ // Error
+ case -1:
+ if(!net_wouldblock()){
+ killConnection(cl);
+ net_perror("RECV");
+ }
+ return;
+ }
+ cl->bufLen += bytesRead;
+ while(1){
+ x = memchr(cl->buf, '\n', cl->bufLen);
+ if(!x) break;
+ tmp = *(x+1);
+ *(x+1) = '\0';
+ processPacket(cl);
+ *(x+1) = tmp;
+ memmove(cl->buf, x+1, cl->buf + cl->bufLen-(x+1));
+ cl->bufLen -= x+1 - cl->buf;
+ }
+ }
}