static void tcpserver_socketreceiver_read(t_tcpserver_socketreceiver *x, int fd) { int readto = (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1); int ret, i; t_tcpserver *y = x->sr_owner; y->x_sock_fd = fd; /* the input buffer might be full. If so, drop the whole thing */ if (readto == x->sr_inhead) { post("%s: dropped message", objName); x->sr_inhead = x->sr_intail = 0; readto = INBUFSIZE; } else { ret = recv(fd, x->sr_inbuf + x->sr_inhead, readto - x->sr_inhead, 0); if (ret < 0) { sys_sockerror("tcpserver: recv"); if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); sys_rmpollfn(fd); sys_closesocket(fd); } else if (ret == 0) { post("%s: connection closed on socket %d", objName, fd); if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); sys_rmpollfn(fd); sys_closesocket(fd); } else { #ifdef DEBUG post ("%s_socketreceiver_read: ret = %d", objName, ret); #endif x->sr_inhead += ret; if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0; /* output client's IP and socket no. */ for(i = 0; i < y->x_nconnections; i++) /* search for corresponding IP */ { if(y->x_sr[i]->sr_fd == y->x_sock_fd) { // outlet_symbol(x->x_connectionip, x->x_sr[i].sr_host); /* find sender's ip address and output it */ y->x_addrbytes[0].a_w.w_float = (y->x_sr[i]->sr_addr & 0xFF000000)>>24; y->x_addrbytes[1].a_w.w_float = (y->x_sr[i]->sr_addr & 0x0FF0000)>>16; y->x_addrbytes[2].a_w.w_float = (y->x_sr[i]->sr_addr & 0x0FF00)>>8; y->x_addrbytes[3].a_w.w_float = (y->x_sr[i]->sr_addr & 0x0FF); outlet_list(y->x_addrout, &s_list, 4L, y->x_addrbytes); break; } } outlet_float(y->x_sockout, y->x_sock_fd); /* the socket number */ tcpserver_socketreceiver_doread(x); } }
static void netrec_socketreceiver_read(t_netrec_socketreceiver *x, int fd) { if (x->sr_udp) /* UDP ("datagram") socket protocol */ netrec_socketreceiver_getudp(x, fd); else /* TCP ("streaming") socket protocol */ { char *semi; int readto = (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1); int ret; t_netrec *y = x->sr_owner; y->x_sock_fd = fd; /* the input buffer might be full. If so, drop the whole thing */ if (readto == x->sr_inhead) { fprintf(stderr, "netrec: dropped message"); x->sr_inhead = x->sr_intail = 0; readto = INBUFSIZE; } else { ret = recv(fd, x->sr_inbuf + x->sr_inhead, readto - x->sr_inhead, 0); if (ret < 0) { sys_sockerror("recv"); if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); sys_rmpollfn(fd); sys_closesocket(fd); } else if (ret == 0) { post("netrec: connection closed on socket %d", fd); if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); sys_rmpollfn(fd); sys_closesocket(fd); } else { x->sr_inhead += ret; if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0; while (netrec_socketreceiver_doread(x)) { outlet_setstacklim(); if (x->sr_socketreceivefn) (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf); else binbuf_eval(inbinbuf, 0, 0, 0); } } } } }
static void streamout13_connect(t_streamout13 *x, t_symbol *hostname, t_floatarg fportno) { struct sockaddr_in server; struct hostent *hp; int sockfd; int portno = fportno; x->hostname = hostname; x->portno = (int) fportno; if (x->x_fd >= 0) { error("streamout13_connect: already connected - reconnecting"); sys_closesocket(x->x_fd); x->x_fd = -1; outlet_float(x->x_obj.ob_outlet, 0); } /* create a socket */ sockfd = socket(AF_INET, x->x_protocol, 0); if (sockfd < 0) { post("streamout13: Connection to %s on port %d failed",hostname->s_name,portno); sys_sockerror("socket"); return; } /* connect socket using hostname provided in command line */ server.sin_family = AF_INET; hp = gethostbyname(hostname->s_name); if (hp == 0) { post("bad host?\n"); return; } memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); /* assign client port number */ server.sin_port = htons((u_short)portno); /* try to connect. LATER make a separate thread to do this because it might block */ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) { sys_sockerror("connecting stream socket"); sys_closesocket(sockfd); return; } post("connected host %s on port %d",hostname->s_name, portno); x->x_fd = sockfd; outlet_float(x->x_obj.ob_outlet, 1); }
static void netserver_socketreceiver_read(t_netserver_socketreceiver *x, int fd) { char *semi; int readto = (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1); int ret; t_netserver *y = x->sr_owner; y->x_sock_fd = fd; /* the input buffer might be full. If so, drop the whole thing */ if (readto == x->sr_inhead) { if (y->x_log_pri >= LOG_ERR) post("netserver: dropped message"); x->sr_inhead = x->sr_intail = 0; readto = INBUFSIZE; } else { ret = recv(fd, x->sr_inbuf + x->sr_inhead, readto - x->sr_inhead, 0); if (ret < 0) { sys_sockerror("recv"); if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); sys_rmpollfn(fd); sys_closesocket(fd); } else if (ret == 0) { if (y->x_log_pri >= LOG_NOTICE) post("netserver: << connection closed on socket %d", fd); if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); sys_rmpollfn(fd); sys_closesocket(fd); } else { x->sr_inhead += ret; if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0; while (netserver_socketreceiver_doread(x)) { outlet_setstacklim(); if (x->sr_socketreceivefn) (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf); else binbuf_eval(inbinbuf, 0, 0, 0); } } } }
static void netserver_free(t_netserver *x) { int i; for(i = 0; i < x->x_nconnections; i++) { sys_rmpollfn(x->x_fd[i]); sys_closesocket(x->x_fd[i]); } if (x->x_connectsocket >= 0) { sys_rmpollfn(x->x_connectsocket); sys_closesocket(x->x_connectsocket); } binbuf_free(inbinbuf); }
static void netsend_readbin(t_netsend *x, int fd) { unsigned char inbuf[MAXPDSTRING]; int ret = recv(fd, inbuf, MAXPDSTRING, 0), i; if (!x->x_msgout) { bug("netsend_readbin"); return; } if (ret <= 0) { if (ret < 0) sys_sockerror("recv"); sys_rmpollfn(fd); sys_closesocket(fd); if (x->x_obj.ob_pd == netreceive_class) netreceive_notify((t_netreceive *)x, fd); } else if (x->x_protocol == SOCK_DGRAM) { t_atom *ap = (t_atom *)alloca(ret * sizeof(t_atom)); for (i = 0; i < ret; i++) SETFLOAT(ap+i, inbuf[i]); outlet_list(x->x_msgout, 0, ret, ap); } else { for (i = 0; i < ret; i++) outlet_float(x->x_msgout, inbuf[i]); } }
static void udpreceive_read(t_oudpreceive *x, int sockfd) { int i, read = 0; struct sockaddr_in from; socklen_t fromlen = sizeof(from); t_atom output_atom; long addr; unsigned short port; read = recvfrom(sockfd, x->x_msginbuf, MAX_UDP_RECEIVE, 0, (struct sockaddr *)&from, &fromlen); #ifdef DEBUG post("udpreceive_read: read %lu x->x_connectsocket = %d", read, x->x_connectsocket); #endif /* get the sender's ip */ addr = ntohl(from.sin_addr.s_addr); port = ntohs(from.sin_port); x->x_addrbytes[0].a_w.w_float = (addr & 0xFF000000)>>24; x->x_addrbytes[1].a_w.w_float = (addr & 0x0FF0000)>>16; x->x_addrbytes[2].a_w.w_float = (addr & 0x0FF00)>>8; x->x_addrbytes[3].a_w.w_float = (addr & 0x0FF); x->x_addrbytes[4].a_w.w_float = port; outlet_anything(x->x_addrout, gensym("from"), 5L, x->x_addrbytes); if (read < 0) { udpreceive_sock_err(x, "udpreceive_read"); sys_closesocket(x->x_connectsocket); return; } if((read % 4) == 0){ char buf[read]; memcpy(buf, x->x_msginbuf, read); critical_exit(x->lock); omax_util_outletOSC(x->outlet, read, buf); OSC_MEM_INVALIDATE(buf); //oudp_sendData(x, t, x->slipibuf); }else{ critical_exit(x->lock); //object_error((t_object *)x, "bad packet: not a multiple of 4 length"); } /* if (read > 0) { for (i = 0; i < read; ++i) { oudp_decode(x, (unsigned char)x->x_msginbuf[i]); } oudp_decode(x, END); x->x_total_received += read; SETFLOAT(&output_atom, read); outlet_anything(x->x_addrout, gensym("received"), 1, &output_atom); }*/ }
static void udpreceive_free(t_udpreceive *x) { if (x->x_connectsocket >= 0) { sys_rmpollfn(x->x_connectsocket); sys_closesocket(x->x_connectsocket); } }
static void netreceive_free(t_netreceive *x) { /* LATER make me clean up open connections */ if (x->x_connectsocket >= 0) { sys_rmpollfn(x->x_connectsocket); sys_closesocket(x->x_connectsocket); } }
static void tcpsend_connect(t_tcpsend *x, t_symbol *hostname, t_floatarg fportno) { struct sockaddr_in server; struct hostent *hp; int sockfd; int portno = fportno; int intarg; memset(&server, 0, sizeof(server)); if (x->x_fd >= 0) { error("tcpsend: already connected"); return; } /* create a socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); DEBUG("send socket %d\n", sockfd); if (sockfd < 0) { sys_sockerror("tcpsend: socket"); return; } /* connect socket using hostname provided in command line */ server.sin_family = AF_INET; hp = gethostbyname(hostname->s_name); if (hp == 0) { post("tcpsend: bad host?\n"); return; } /* for stream (TCP) sockets, specify "nodelay" */ intarg = 1; if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&intarg, sizeof(intarg)) < 0) post("tcpsend: setsockopt (TCP_NODELAY) failed\n"); memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); /* assign client port number */ server.sin_port = htons((u_short)portno); post("tcpsend: connecting to port %d", portno); /* try to connect. */ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) { sys_sockerror("tcpsend: connecting stream socket"); sys_closesocket(sockfd); return; } x->x_fd = sockfd; x->x_sender=iemnet__sender_create(sockfd, 0); outlet_float(x->x_obj.ob_outlet, 1); }
static void streamout13_disconnect(t_streamout13 *x) { if (x->x_fd >= 0) { sys_closesocket(x->x_fd); x->x_fd = -1; outlet_float(x->x_obj.ob_outlet, 0); } }
static void netsend_disconnect(t_netsend *x) { if (x->x_fd >= 0) { sys_closesocket(x->x_fd); x->x_fd = -1; outlet_float(x->x_obj.ob_outlet, 0); } }
static void netreceive_closeall(t_netreceive *x) { int i; for (i = 0; i < x->x_nconnections; i++) { sys_rmpollfn(x->x_connections[i]); sys_closesocket(x->x_connections[i]); } x->x_connections = (int *)t_resizebytes(x->x_connections, x->x_nconnections * sizeof(int), 0); x->x_nconnections = 0; if (x->x_ns.x_sockfd >= 0) { sys_rmpollfn(x->x_ns.x_sockfd); sys_closesocket(x->x_ns.x_sockfd); } x->x_ns.x_sockfd = -1; }
static void udpreceive_read(t_udpreceive *x, int sockfd) { int i, read = 0; struct sockaddr_in6 from; socklen_t fromlen = sizeof(from); t_atom output_atom; long addr; unsigned short port; read = recvfrom(sockfd, x->x_msginbuf, MAX_UDP_RECEIVE, 0, (struct sockaddr *)&from, &fromlen); #ifdef DEBUG post("udpreceive_read: read %lu x->x_connectsocket = %d", read, x->x_connectsocket); #endif char buf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &from.sin6_addr, buf, INET6_ADDRSTRLEN ); t_atom out; out.a_type = A_SYMBOL; out.a_w.w_symbol = gensym(buf); outlet_anything(x->x_addrout, gensym("from"), 1L, &out); /* get the sender's ip */ /* addr = ntohl(from.sin6_addr); port = ntohs(from.sin6_port); x->x_addrbytes[0].a_w.w_float = (addr & 0xFF000000)>>24; x->x_addrbytes[1].a_w.w_float = (addr & 0x0FF0000)>>16; x->x_addrbytes[2].a_w.w_float = (addr & 0x0FF00)>>8; x->x_addrbytes[3].a_w.w_float = (addr & 0x0FF); x->x_addrbytes[4].a_w.w_float = port; outlet_anything(x->x_addrout, gensym("from"), 5L, x->x_addrbytes); */ if (read < 0) { udpreceive_sock_err(x, "udpreceive_read"); sys_closesocket(x->x_connectsocket); return; } if (read > 0) { for (i = 0; i < read; ++i) { /* convert the bytes in the buffer to floats in a list */ x->x_msgoutbuf[i].a_w.w_float = (float)(unsigned char)x->x_msginbuf[i]; } x->x_total_received += read; SETFLOAT(&output_atom, read); outlet_anything(x->x_addrout, gensym("received"), 1, &output_atom); /* send the list out the outlet */ if (read > 1) outlet_list(x->x_msgout, &s_list, read, x->x_msgoutbuf); else outlet_float(x->x_msgout, x->x_msgoutbuf[0].a_w.w_float); } }
static void oudpreceive_free(t_oudpreceive *x) { if (x->x_connectsocket >= 0) { sys_rmpollfn(x->x_connectsocket); sys_closesocket(x->x_connectsocket); } critical_free(x->lock); }
static void netsend_disconnect(t_netsend *x) { if (x->x_fd >= 0) { #ifndef ROCKBOX sys_closesocket(x->x_fd); #endif x->x_fd = -1; outlet_float(x->x_obj.ob_outlet, 0); } }
static void *tcpclient_child_connect(void *w) { t_tcpclient *x = (t_tcpclient*) w; struct sockaddr_in server; struct hostent *hp; int sockfd; if (x->x_fd >= 0) { error("%s_child_connect: already connected", objName); return (x); } /* create a socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); #ifdef DEBUG post("%s: send socket %d\n", objName, sockfd); #endif if (sockfd < 0) { sys_sockerror("tcpclient: socket"); return (x); } /* connect socket using hostname provided in command line */ server.sin_family = AF_INET; hp = gethostbyname(x->x_hostname); if (hp == 0) { sys_sockerror("tcpclient: bad host?\n"); return (x); } memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); /* assign client port number */ server.sin_port = htons((u_short)x->x_port); if (x->x_verbosity) post("%s: connecting socket %d to port %d", objName, sockfd, x->x_port); /* try to connect */ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) { sys_sockerror("tcpclient: connecting stream socket"); sys_closesocket(sockfd); return (x); } x->x_fd = sockfd; x->x_addr = ntohl(*(long *)hp->h_addr); /* outlet_float is not threadsafe ! */ // outlet_float(x->x_obj.ob_outlet, 1); x->x_connectstate = 1; x->x_blocked = 0; /* use callback instead to set outlet */ clock_delay(x->x_clock, 0); return (x); }
static void tcpsend_disconnect(t_tcpsend *x) { if (x->x_fd >= 0) { if(x->x_sender)iemnet__sender_destroy(x->x_sender, 0); x->x_sender=NULL; sys_closesocket(x->x_fd); x->x_fd = -1; outlet_float(x->x_obj.ob_outlet, 0); post("tcpsend: disconnected"); } }
static void tcpclient_disconnect(t_tcpclient *x) { if (x->x_fd >= 0) { sys_closesocket(x->x_fd); x->x_fd = -1; x->x_connectstate = 0; outlet_float(x->x_outconnect, 0); post("%s: disconnected", objName); } else post("%s: not connected", objName); }
static void tcpclient_rcv(t_tcpclient *x) { int sockfd = x->x_fd; int ret; int i; fd_set readset; fd_set exceptset; struct timeval ztout; if(x->x_connectstate) { /* check if we can read/write from/to the socket */ FD_ZERO(&readset); FD_ZERO(&exceptset); FD_SET(x->x_fd, &readset ); FD_SET(x->x_fd, &exceptset ); ztout.tv_sec = 0; ztout.tv_usec = 0; ret = select(sockfd+1, &readset, NULL, &exceptset, &ztout); if(ret < 0) { pd_error(x, "%s: unable to read from socket", objName); sys_closesocket(sockfd); return; } if(FD_ISSET(sockfd, &readset) || FD_ISSET(sockfd, &exceptset)) { /* read from server */ ret = recv(sockfd, x->x_msginbuf, MAX_TCPCLIENT_SEND_BUF, 0); if(ret > 0) { #ifdef DEBUG x->x_msginbuf[ret] = 0; post("%s: received %d bytes ", objName, ret); #endif if (x->x_dump)tcp_client_hexdump(x, ret); for (i = 0; i < ret; ++i) { /* convert the bytes in the buffer to floats in a list */ x->x_msgoutbuf[i].a_w.w_float = (float)x->x_msginbuf[i]; } /* find sender's ip address and output it */ x->x_addrbytes[0].a_w.w_float = (x->x_addr & 0xFF000000)>>24; x->x_addrbytes[1].a_w.w_float = (x->x_addr & 0x0FF0000)>>16; x->x_addrbytes[2].a_w.w_float = (x->x_addr & 0x0FF00)>>8; x->x_addrbytes[3].a_w.w_float = (x->x_addr & 0x0FF); outlet_list(x->x_addrout, &s_list, 4L, x->x_addrbytes); /* send the list out the outlet */ if (ret > 1) outlet_list(x->x_msgout, &s_list, ret, x->x_msgoutbuf); else outlet_float(x->x_msgout, x->x_msgoutbuf[0].a_w.w_float); }
static void netreceive_free(t_netreceive *x) { #ifdef ROCKBOX if(receiver && receiver == x) receiver = NULL; #else /* ROCKBOX */ /* LATER make me clean up open connections */ if (x->x_connectsocket >= 0) { sys_rmpollfn(x->x_connectsocket); sys_closesocket(x->x_connectsocket); } #endif /* ROCKBOX */ }
static void *netdist_child_connect(void *w) { int i; t_netdist *x = (t_netdist*) w; struct sockaddr_in server; struct hostent *hp; int sockfd; int portno; i = x->x_numconnect + 1; portno = x->x_port[i]; /* create a socket */ sockfd = socket(AF_INET, x->x_protocol, 0); #if 0 fprintf(stderr, "send socket %d\n", sockfd); #endif if (sockfd < 0) { sys_sockerror("socket"); return (x); } /* connect socket using hostname provided in command line */ server.sin_family = AF_INET; hp = gethostbyname(x->x_hostname[i]); if (hp == 0) { post("bad host?\n"); return (x); } memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); /* assign client port number */ server.sin_port = htons((u_short)portno); post("connecting to port %d", portno); /* try to connect */ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) { sys_sockerror("connecting stream socket"); sys_closesocket(sockfd); return (x); } x->x_fd[i] = sockfd; /* outlet_float is not threadsafe ! */ // outlet_float(x->x_obj.ob_outlet, 1); x->x_numconnect++; /* count connection */ /* use callback instead to set outlet */ clock_delay(x->x_clock, 0); return (x); }
/* close a socket properly */ void iemnet__closesocket(int sockfd, int verbose) { if(sockfd >=0) { #ifndef SHUT_RDWR # define SHUT_RDWR 2 #endif int how=SHUT_RDWR; int err = shutdown(sockfd, how); /* needed on linux, since the recv won't shutdown on sys_closesocket() alone */ if(verbose && err) { perror("iemnet:socket-shutdown"); } sys_closesocket(sockfd); } }
static void udpclient_disconnect(t_udpclient *x) { if (x->x_fd >= 0) { DEBUG("disconnect %x %x", x->x_sender, x->x_receiver); if(x->x_receiver)iemnet__receiver_destroy(x->x_receiver); x->x_receiver=NULL; if(x->x_sender)iemnet__sender_destroy(x->x_sender); x->x_sender=NULL; sys_closesocket(x->x_fd); x->x_fd = -1; x->x_connectstate = 0; outlet_float(x->x_connectout, 0); } else pd_error(x, "[%s] not connected", objName); }
static void tcpclient_disconnect(t_tcpclient *x) { int i; if (x->x_fd >= 0) { for (i = 0; i < MAX_TCPCLIENT_THREADS;++i) { /* wait for any sender threads to finish */ while (x->x_tsp[i].threadisvalid != 0); } sys_closesocket(x->x_fd); x->x_fd = -1; x->x_connectstate = 0; outlet_float(x->x_connectout, 0); if (x->x_verbosity) post("%s: disconnected", objName); } else post("%s: not connected", objName); }
static void tcpclient_disconnect(t_tcpclient *x) { if (x->x_fd >= 0) { int fd=x->x_fd; x->x_fd = -1; DEBUG("disconnecting %x", x); if(x->x_sender)iemnet__sender_destroy(x->x_sender); x->x_sender=NULL; if(x->x_receiver)iemnet__receiver_destroy(x->x_receiver); x->x_receiver=NULL; DEBUG("disconnect cleaning up %x", x); sys_closesocket(fd); x->x_connectstate = 0; outlet_float(x->x_connectout, 0); } else pd_error(x, "%s: not connected", objName); }
static void netdist_disconnect(t_netdist *x, t_symbol *hostname, t_floatarg port) { int i, j; for(i = 0; i <= x->x_numconnect; i++) { if((hostname->s_name == x->x_hostname[i]) && ((int)port == x->x_port[i])) { /* search for connection */ if (x->x_fd[i] >= 0) { sys_closesocket(x->x_fd[i]); x->x_fd[i] = -1; x->x_numconnect--; outlet_float(x->x_obj.ob_outlet, x->x_numconnect + 1); for(j = i; j <= x->x_numconnect; j++) { x->x_hostname[j] = x->x_hostname[j + 1]; x->x_port[j] = x->x_port[j + 1]; x->x_fd[j] = x->x_fd[j + 1]; } } } } }
static void netrec_socketreceiver_getudp(t_netrec_socketreceiver *x, int fd) { char buf[INBUFSIZE+1]; int ret = recv(fd, buf, INBUFSIZE, 0); if (ret < 0) { sys_sockerror("recv"); sys_rmpollfn(fd); sys_closesocket(fd); } else if (ret > 0) { buf[ret] = 0; #if 0 post("%s", buf); #endif if (buf[ret-1] != '\n') { #if 0 buf[ret] = 0; error("dropped bad buffer %s\n", buf); #endif } else { char *semi = strchr(buf, ';'); if (semi) *semi = 0; binbuf_text(inbinbuf, buf, strlen(buf)); outlet_setstacklim(); if (x->sr_socketreceivefn) (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf); else bug("netrec_socketreceiver_getudp"); } } }
static int udpreceive_new_socket(t_udpreceive *x, char *address, int port) { // return nonzero if successful in creating and binding a socket int sockfd; int intarg; int multicast_joined = 0; struct sockaddr_in6 server; struct hostent *hp; #if defined __APPLE__ || defined _WIN32 struct ipv6_mreq mreq; #else struct ipv6_mreqn mreq; #endif if (x->x_connectsocket >= 0) { // close the existing socket first sys_rmpollfn(x->x_connectsocket); sys_closesocket(x->x_connectsocket); } /* create a socket */ sockfd = socket(AF_INET6, SOCK_DGRAM, 0); #ifdef DEBUG post("udpreceive_new: socket %d port %d", sockfd, portno); #endif if (sockfd < 0) { udpreceive_sock_err(x, "udpreceive: socket"); return 0; } server.sin6_family = AF_INET6; if (address[0] == 0) server.sin6_addr = in6addr_any; else { hp = gethostbyname2(address, AF_INET6); if (hp == 0) { pd_error(x, "udpreceive: bad host?\n"); return 0; } //memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); inet_pton(AF_INET6, address, &server.sin6_addr); } /* enable delivery of all multicast or broadcast (but not unicast) * UDP datagrams to all sockets bound to the same port */ intarg = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&intarg, sizeof(intarg)) < 0) { udpreceive_sock_err(x, "udpreceive: setsockopt (SO_REUSEADDR) failed"); return 0; } /* assign server port number */ server.sin6_port = htons((u_short)port); if(IN6_IS_ADDR_MULTICAST(&server.sin6_addr)) post("need to impletment mulitcast"); /* if a multicast address was specified, join the multicast group */ /* hop count defaults to 1 so we won't leave the subnet*/ /* if (0xE0000000 == (ntohl(server.sin_addr.s_addr) & 0xF0000000)) { server.sin_addr.s_addr = INADDR_ANY; // first bind the socket to INADDR_ANY if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) { udpreceive_sock_err(x, "udpreceive: bind"); sys_closesocket(sockfd); return 0; } // second join the multicast group memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); #if defined __APPLE__ || defined _WIN32 mreq.imr_multiaddr.s_addr = server.sin_addr.s_addr; mreq.imr_interface.s_addr = INADDR_ANY;// can put a specific local IP address here if host is multihomed #else mreq.imr_multiaddr.s_addr = server.sin_addr.s_addr; mreq.imr_address.s_addr = INADDR_ANY; mreq.imr_ifindex = 0; #endif //__APPLE__ || _WIN32 if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) udpreceive_sock_err(x, "udpreceive: setsockopt IP_ADD_MEMBERSHIP"); else { multicast_joined = 1; post ("udpreceive: added to multicast group"); } } else {*/ /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) { udpreceive_sock_err(x, "udpreceive: bind"); sys_closesocket(sockfd); return 0; } // } x->x_multicast_joined = multicast_joined; x->x_connectsocket = sockfd; x->x_total_received = 0L; sys_addpollfn(x->x_connectsocket, (t_fdpollfn)udpreceive_read, x); return 1; }
static void *netserver_new(t_floatarg fportno) { t_netserver *x; int i; struct sockaddr_in server; int sockfd, portno = fportno; x = (t_netserver *)pd_new(netserver_class); /* set default debug message level */ x->x_log_pri = LOG_ERR; /* create a socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); if (x->x_log_pri >= LOG_NOTICE) post("netserver: receive socket %d", sockfd); if (sockfd < 0) { sys_sockerror("socket"); return (0); } server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; #ifdef IRIX /* this seems to work only in IRIX but is unnecessary in Linux. Not sure what NT needs in place of this. */ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0) post("setsockopt failed\n"); #endif /* assign server port number */ server.sin_port = htons((u_short)portno); /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) { sys_sockerror("bind"); sys_closesocket(sockfd); return (0); } x->x_msgout = outlet_new(&x->x_obj, &s_anything); /* streaming protocol */ if (listen(sockfd, 5) < 0) { sys_sockerror("listen"); sys_closesocket(sockfd); sockfd = -1; } else { sys_addpollfn(sockfd, (t_fdpollfn)netserver_connectpoll, x); x->x_connectout = outlet_new(&x->x_obj, &s_float); x->x_clientno = outlet_new(&x->x_obj, &s_float); x->x_connectionip = outlet_new(&x->x_obj, &s_symbol); inbinbuf = binbuf_new(); } x->x_connectsocket = sockfd; x->x_nconnections = 0; for(i = 0; i < MAX_CONNECT; i++)x->x_fd[i] = -1; return (x); }