void SocksConnection::WriteSocksReply(SocksReplyCode reason, const QHostAddress &addr, quint16 port) { QHostAddress a = (addr.isNull() || addr.protocol() != QAbstractSocket::IPv4Protocol) ? QHostAddress("8.8.8.8") : addr; QByteArray reply(4, 0); reply[0] = (uchar)SocksVersion_5; // Protocol version reply[1] = reason; // Reply reply[2] = 0x00; // Reserved reply[3] = SocksAddress_IPv4; // Address type // reply[4] IP Octet 1 // reply[5] IP Octet 2 // reply[6] IP Octet 3 // reply[7] IP Octet 3 // reply[8] Port Octet 1 // reply[9] Port Octet 1 QDataStream stream(&reply, QIODevice::Append); stream.setByteOrder(QDataStream::BigEndian); stream << a.toIPv4Address(); stream << port; for(int i=0;i<reply.count();i++) { qDebug() << "SOCKS reply" << i << "|" << (unsigned char)reply[i]; } TryWrite(reply); }
int FifoPush(Fifo *fifo, void *data, int size) { struct FifoElem *cur; int rv = FifoFlush(fifo); if (rv == -1) { return -1; } if (EMPTY(fifo)) { int newSize = TryWrite(fifo->fd, data, size); if (newSize == -1) { return -1; } else if (newSize == size) { return 1; } else { data += newSize; size -= newSize; } } else if (FULL(fifo)) { return 0; } void *dataCopy = malloc(size); memcpy(dataCopy, data, size); fifo->Tail = (fifo->Tail+1)%(FIFO_ELEMS*2); cur = &TAIL_ELEM(fifo); cur->DataCur = cur->DataStart = dataCopy; cur->Remaining = size; return 1; }
void SocksConnection::SendMethodsReply() { // Reply is two bytes: // byte[0] = version (0x05) // byte[1] = method (0x00 is no auth) QByteArray reply(2, 0); reply[0] = (uchar) SocksVersion_5; for(int i=0; i<_methods_buf.count(); i++) { qDebug() << "METHODS[]" << i << "=" << (int)((uchar)_methods_buf[i]); } bool close = false; // If the SOCKS proto version is wrong, or if the // authentication method is unacceptable if((_version != (uchar)SocksVersion_5) || !_methods_buf.contains(SocksAuth_NoAuth)) { qDebug() << "Sending invalid reply header for protocol " << (int)_version; reply[1] = ((uchar)SocksAuth_NoneAcceptable); close = true; } else { qDebug() << "Sending OK method reply"; reply[1] = (uchar)SocksAuth_NoAuth; _state = ConnState_WaitingForRequestHeader; } TryWrite(reply); if(close) Close(); }
void SocksConnection::HandleTcpResponse(QSharedPointer<Packet> pp) { TcpResponsePacket *rp = dynamic_cast<TcpResponsePacket*>(pp.data()); if(!rp) { qWarning() << "SOCKS Could not cast TcpResponsePacket"; return; } qDebug() << "SOCKS response : " << rp->GetResponseData().count(); TryWrite(rp->GetResponseData()); }
//---------------------------------------------------------------------------------------------- void CRingBuffer::Write(unsigned char* pData, unsigned int Size) { Assert(Size < m_Size / 2); // writes greater than half buffer size can cause a lock condition bool Res = false; while(!Res) { Res = TryWrite(pData, Size); if(!Res) { Sleep(0); } } }
void NetworkManager::OnConnect() { // accept client // register new client socket to epoll instance int clientFd; sockaddr_in clientAddr; socklen_t addrLen = 0; // #4. accept if((clientFd = accept(m_serverFd, (struct sockaddr*)&clientAddr, &addrLen)) < 0) { fprintf(stderr, "[ERROR] : ACCEPT ERROR\n"); exit(-1); } // make socket non-blocking int flags = fcntl(clientFd, F_GETFL, 0); if(flags < 0) { fprintf(stderr, "[ERROR] : MAKE SOCKET NONBLOCKING ERROR\n"); exit(-1); } flags = fcntl(clientFd, F_SETFL, flags | O_NONBLOCK); Session* pSession = new Session(clientFd, clientAddr); pSession->state = SS_CONNECTED; m_pSessionMap.insert(std::pair<int, Session*>(clientFd, pSession)); struct epoll_event epollEvent; epollEvent.events = EPOLLIN | EPOLLERR; //| EPOLLOUT | EPOLLERR; epollEvent.data.fd = clientFd; // register server fd to epoll if(epoll_ctl(m_epollFdList[clientFd%NETWORK_THREAD_NUM], EPOLL_CTL_ADD, clientFd, &epollEvent) < 0) { fprintf(stderr, "[ERROR] : EPOLL CTL ERROR\n"); exit(-1); } // give session to user Packet writePacket; S_PT_SESSION_U data; data.sessionId = clientFd; MAKE_PT_SESSION_U(writePacket.buffer, writePacket.size, data); TryWrite(clientFd, writePacket); printf("%d session connected\n", clientFd); }
void CDatagrams::OnRun() { if ( ! IsValid() ) return; DHT.OnRun(); TryWrite(); ManageOutput(); do { ManagePartials(); } while ( TryRead() ); Measure(); }
static int FifoFlushOnce(Fifo *fifo) { int rv; if (EMPTY(fifo)) return 0; do { struct FifoElem *cur = &HEAD_ELEM(fifo); int written = TryWrite(fifo->fd, cur->DataCur, cur->Remaining); if (written == -1) { return -1; } rv += written; if (written == cur->Remaining) { FifoPop(fifo); continue; } else { cur->DataCur += written; cur->Remaining -= written; } } while (0); return rv; }
BOOL CDatagrams::Send(const SOCKADDR_IN* pHost, CPacket* pPacket, BOOL bRelease, LPVOID pToken, BOOL bAck) { ASSERT( pHost != NULL && pPacket != NULL ); if ( ! IsValid() || Security.IsDenied( &pHost->sin_addr ) ) { if ( bRelease ) pPacket->Release(); return FALSE; } if ( pPacket->m_nProtocol != PROTOCOL_G2 ) { CBuffer pBuffer; pPacket->ToBuffer( &pBuffer, false ); m_nOutPackets++; switch ( pPacket->m_nProtocol ) { case PROTOCOL_G1: Statistics.Current.Gnutella1.Outgoing++; break; case PROTOCOL_ED2K: Statistics.Current.eDonkey.Outgoing++; break; case PROTOCOL_DC: Statistics.Current.DC.Outgoing++; break; case PROTOCOL_BT: Statistics.Current.BitTorrent.Outgoing++; break; //default: // ; // Other? } pPacket->SmartDump( pHost, TRUE, TRUE ); if ( bRelease ) pPacket->Release(); CNetwork::SendTo( m_hSocket, (LPSTR)pBuffer.m_pBuffer, pBuffer.m_nLength, pHost ); return TRUE; } // Gnutella2 uses SGP-powered datagrams if ( m_pOutputFree == NULL || m_pBufferFree == NULL ) { if ( m_pOutputLast == NULL ) { if ( bRelease ) pPacket->Release(); theApp.Message( MSG_DEBUG, _T("CDatagrams output frames exhausted.") ); return FALSE; } Remove( m_pOutputLast ); } if ( m_pBufferFree == NULL ) { if ( bRelease ) pPacket->Release(); theApp.Message( MSG_DEBUG, _T("CDatagrams output frames really exhausted.") ); return FALSE; } CDatagramOut* pDG = m_pOutputFree; m_pOutputFree = m_pOutputFree->m_pNextHash; if ( m_nInFrags < 1 ) bAck = FALSE; pDG->Create( pHost, (CG2Packet*)pPacket, m_nSequence++, m_pBufferFree, bAck ); m_pBufferFree = m_pBufferFree->m_pNext; m_nBufferFree--; pDG->m_pToken = pToken; pDG->m_pNextTime = NULL; pDG->m_pPrevTime = m_pOutputFirst; if ( m_pOutputFirst ) m_pOutputFirst->m_pNextTime = pDG; else m_pOutputLast = pDG; m_pOutputFirst = pDG; BYTE nHash = BYTE( ( pHost->sin_addr.S_un.S_un_b.s_b1 + pHost->sin_addr.S_un.S_un_b.s_b2 + pHost->sin_addr.S_un.S_un_b.s_b3 + pHost->sin_addr.S_un.S_un_b.s_b4 + pHost->sin_port + pDG->m_nSequence ) & 0xff ); CDatagramOut** pHash = m_pOutputHash + ( nHash & HASH_MASK ); if ( *pHash ) (*pHash)->m_pPrevHash = &pDG->m_pNextHash; pDG->m_pNextHash = *pHash; pDG->m_pPrevHash = pHash; *pHash = pDG; m_nOutPackets++; Statistics.Current.Gnutella2.Outgoing++; #ifdef DEBUG_UDP theApp.Message( MSG_DEBUG, _T("UDP: Queued SGP (#%i) x%i for %s:%lu"), pDG->m_nSequence, pDG->m_nCount, (LPCTSTR)CString( inet_ntoa( pDG->m_pHost.sin_addr ) ), htons( pDG->m_pHost.sin_port ) ); #endif pPacket->SmartDump( pHost, TRUE, TRUE ); if ( bRelease ) pPacket->Release(); TryWrite(); return TRUE; }