/* * Copyright (c) 2004 Teodor Sigaev * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "tlog.h" #include "connection.h" #include "top.h" #include "tmalloc.h" static void getTopData(TC_Connection *conn) { TCMsg *pmsg; conn->len = TCMSGHDRSZ + MUHDRSZ + cfg.mu->number * sizeof(UnitInfo); conn->buf = trealloc( conn->buf, conn->len ); pmsg = conn->buf; pmsg->len = conn->len; pmsg->type = TOPGETTYPE; memcpy( pmsg->data, cfg.mu, pmsg->len - TCMSGHDRSZ ); ((MassiveUnit*)pmsg->data)->maxnumber = cfg.mu->number; TC_Send(conn); } static void gotLongMessage( TC_Connection *conn ) { TCMsg *pmsg = conn->buf; if ( conn->ptr -(char*) conn->buf < TCMSGHDRSZ ) { tlog(TL_ALARM,"Wrong size of long message (%d bytes)", conn->ptr - (char*)conn->buf); conn->state = CS_ERROR; return; } switch(pmsg->type) { case TOPGETTYPE: getTopData(conn); break; default: tlog(TL_ALARM,"Got unknown packet type: %u (%08x)", pmsg->type, pmsg->type); conn->state = CS_ERROR; } } static void sendedLongMessage( TC_Connection *conn ) { TCMsg *pmsg = conn->buf; switch(pmsg->type) { case TOPGETTYPE: conn->state = CS_FINISH; break; default: tlog(TL_ALARM,"Send unknown packet type: %u(0x%08x)", pmsg->type, pmsg->type); conn->state = CS_ERROR; } } void ConnectionWorks() { int i; TC_Connection *conn; for(i=TC_SERVER_CONN_START; istate ) { case CS_INPROCESS: TC_ServerConnect( conn, 0 ); break; case CS_CONNECTED: /* we have connected to remote host */ TC_Send( conn ); break; case CS_FINISHSEND: sendedLongMessage( conn ); break; case CS_FINISHREAD: gotLongMessage( conn ); break; case CS_READ: if ( conn->readyio ) { TC_Read( conn, TCMSGHDRSZ ); if ( conn->state != CS_READ ) i--; /* check it one more time */ } break; case CS_SEND: if ( conn->readyio ) { TC_Send( conn ); if ( conn->state != CS_SEND ) i--; /* check it one more time */ } break; /* ignore */ case CS_OK: case CS_AGAIN: case CS_WAIT: /* ??? */ break; /* out */ case CS_TIMEOUT: case CS_CLOSED: case CS_NOTINITED: case CS_FINISH: case CS_ERROR: default: tlog(TL_DEBUG, "Clear N%d connection", i); TC_deleteConnectionByN(&cfg.pool,i); i--; } } }