X-Git-Url: https://hackdaworld.org/gitweb/?p=my-code%2Fivac.git;a=blobdiff_plain;f=src%2Fnetwork.c;h=b9c68aa09316e0ba8613daa28998d05edf199c1a;hp=66314f907e7f9b159f271d6e847e7a17355ad576;hb=9fb0ced14058a258508a61f998059a0f9ab005de;hpb=5cefb7a043dc08801cb98524f129b8fc4df6ed6c diff --git a/src/network.c b/src/network.c index 66314f9..b9c68aa 100644 --- a/src/network.c +++ b/src/network.c @@ -27,17 +27,15 @@ int network_init(t_net *net) { addr.sin_port=htons(net->l_port); addr.sin_addr.s_addr=INADDR_ANY; - /* prevent addres in use error message */ - true=1; - if(setsockopt(net->l_fd,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(true))==-1) { - perror("[network] setsockopt call"); - return N_ERROR; - } - if(bind(net->l_fd,(struct sockaddr *)&addr, sizeof(struct sockaddr))==-1) { - perror("[network] bind call"); - return N_ERROR; + /* try harder ... */ + true=1; + if(setsockopt(net->l_fd,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(true))==-1) { + perror("[network] setsockopt call"); + return N_ERROR; + } + puts("[network] reused address"); } if(listen(net->l_fd,MAX_LISTEN_QUEUE)==-1) { @@ -88,7 +86,7 @@ int network_manage_connection(t_net *net) { if(net->connection[i].status&C_HANGUP) { if(close(net->connection[i].fd)==-1) { perror("[network] close call"); - return N_ERROR; + return N_E_CLOSE; } printf("[network] connection %d closed\n",i); net->connection[i].status=0; @@ -118,11 +116,12 @@ int network_manage_connection(t_net *net) { if(connect(net->connection[i].fd,(struct sockaddr *)&addr, sizeof(struct sockaddr))==-1) { perror("[network] connect call"); - return N_ERROR; + return N_E_CONNECT; } - printf("[network] established connection to %s port %d on channel %d\n", - net->connection[i].ip,net->connection[i].port,i); + printf("[network] established connection to "); + printf("%s port %d on channel %d\n",net->connection[i].ip, + net->connection[i].port,i); net->connection[i].status|=C_ESTABL; } @@ -136,6 +135,80 @@ int network_manage_connection(t_net *net) { return N_SUCCESS; } +int network_connect(t_net *net,int channel) { + + if(net->connection[channel].status&C_IN_USE) { + printf("[network] connect failed, channel %02d in use\n",channel); + return N_E_IN_USE; + } + if(!(net->connection[channel].status&C_INFO_A)) { + printf("[network] connect failed, missing configuration for channel %02d\n", + channel); + return N_E_NO_INFO; + } + + /* try connect & return result */ + net->connection[channel].status|=C_IN_USE; + return(network_manage_connection(net)); /* could be other channel too */ +} + +int network_close(t_net *net,int channel) { + + if(!(net->connection[channel].status&C_ESTABL)) { + printf("[network] close failed, channel %02d not active\n",channel); + return N_E_NC; + } + + net->connection[channel].status|=C_HANGUP; + return(network_manage_connection(net)); /* could be other channel too */ +} + +int network_close_all(t_net *net) { + + int channel; + + for(channel=0;channelconnection[channel].status&C_ESTABL) network_close(net,channel); + + return N_SUCCESS; +} + +int network_set_connection_info(t_net *net,int channel,char *ip,int port) { + + if(net->connection[channel].status&C_IN_USE) { + printf("[network] set connection failed, channel %02d in use\n",channel); + return N_E_IN_USE; + } + + strncpy(net->connection[channel].ip,ip,IP_DIGITS); + net->connection[channel].port=port; + net->connection[channel].status|=C_INFO_A; + + return N_SUCCESS; +} + +int network_select(t_net *net,int channel) { + + int mask; + + if(channel==MAX_CONNECTIONS) mask=0xffffffff; + else mask=(1<sendmask|=mask; + + return N_SUCCESS; +} + +int network_deselect(t_net *net,int channel) { + + int mask; + + if(channel==MAX_CONNECTIONS) mask=0; + else mask=~(1<sendmask&=mask; + + return N_SUCCESS; +} + int network_manage_incoming(t_net *net) { int channel; @@ -148,7 +221,7 @@ int network_manage_incoming(t_net *net) { (struct sockaddr *)&addr, &len))==-1) { perror("[network] accept call"); - return N_ERROR; + return N_E_ACCEPT; } strncpy(net->connection[channel].ip,inet_ntoa(addr.sin_addr),IP_DIGITS); net->connection[channel].port=ntohs(addr.sin_port); @@ -160,7 +233,7 @@ int network_manage_incoming(t_net *net) { } puts("[network] maximum connections reached"); - return N_ERROR; + return N_E_MAXC; } int network_send(int fd,unsigned char *data,int datasize) { @@ -192,3 +265,97 @@ int network_receive(int fd,unsigned char *data,int datasize) { return count; } + +int network_udp_listen_init(t_net *net,int port) { + + struct sockaddr_in addr; + + if((net->l_udp_fd=socket(AF_INET,SOCK_DGRAM,0))==-1) { + perror("[network] socket call (udp-receive)"); + return N_ERROR; + } + + memset(&addr,0,sizeof(struct sockaddr)); + addr.sin_family=AF_INET; + addr.sin_port=htons(net->l_udp_port); + addr.sin_addr.s_addr=INADDR_ANY; + if(bind(net->l_udp_fd,(struct sockaddr *)&addr,sizeof(struct sockaddr))==-1) { + perror("[network] bind call (udp)"); + return N_ERROR; + } + + printf("[network] listening on port %d (udp)\n",net->l_udp_port); + + if((net->s_udp_fd=socket(AF_INET,SOCK_DGRAM,0))==-1) { + perror("[network] socket call (udp-send)"); + return N_ERROR; + } + + return N_SUCCESS; +} + +int network_set_udp_ports(t_net *net,int port) { + + net->l_udp_port=port; + + return N_SUCCESS; +} + +int network_udp_receive(t_net *net,int channel, unsigned char *data,int count) { + + struct sockaddr_in addr; + socklen_t len; + + if((count=recvfrom(net->l_udp_fd,data,count,0, + (struct sockaddr *)&addr,&len))==-1) { + perror("[network] recvfrom call"); + return N_ERROR; + } + + if(strncmp(net->connection[channel].ip,inet_ntoa(addr.sin_addr),IP_DIGITS)) { + printf("[network] packet from unknown: %s\n",inet_ntoa(addr.sin_addr)); + return N_UDP_WRONG_SENDER; + } + + return N_SUCCESS; +} + +int network_udp_send(t_net *net,int channel, unsigned char *data,int size) { + + int count,left; + struct sockaddr_in addr; + + count=0; + left=count; + + memset(&addr,0,sizeof(struct sockaddr)); + addr.sin_family=AF_INET; + addr.sin_port=htons(net->l_udp_port); + inet_aton(net->connection[channel].ip,&(addr.sin_addr)); + + while(left) { + if((count=sendto(net->s_udp_fd,data+size-left,left,0, + (struct sockaddr *)&addr,sizeof(struct sockaddr)))==-1) { + perror("[network] sendto call"); + return N_ERROR; + } + left-=count; + } + + return N_SUCCESS; +} + +int network_udp_shutdown(t_net *net) { + + if(close(net->l_udp_fd)==-1) { + perror("[network] close call (udp-receive)"); + return N_ERROR; + } + + if(close(net->s_udp_fd)==-1) { + perror("[network] close call (udp-send)"); + return N_ERROR; + } + + return N_SUCCESS; +}