0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
mongodb/grid/message.cpp

135 lines
3.3 KiB
C++
Raw Normal View History

2007-10-20 01:35:48 +02:00
/* message
todo: authenticate; encrypt?
*/
#include "stdafx.h"
#include "message.h"
2007-11-05 21:12:45 +01:00
#include <time.h>
2007-11-13 22:44:01 +01:00
#include "../util/goodies.h"
2007-11-18 03:10:00 +01:00
#include "protocol.h"
#include "protoimpl.h"
2007-10-20 01:35:48 +02:00
2007-11-18 03:10:00 +01:00
MSGID NextMsgId;
2007-10-20 01:35:48 +02:00
struct MsgStart {
MsgStart() {
2007-11-18 03:10:00 +01:00
NextMsgId = (((unsigned) time(0)) << 16) ^ curTimeMillis();
assert(MsgDataHeaderSize == 16);
assert(sizeof(Fragment) == FragHeader+16);
2007-10-20 01:35:48 +02:00
}
} msgstart;
2007-11-18 03:10:00 +01:00
int nextChannel = curTimeMillis() & 0x3fff;
MessagingPort::MessagingPort(int c) {
myChannel = c;
if( c == AUTOASSIGNCHANNEL ) {
myChannel = nextChannel++;
if( myChannel > 0x7000 ) {
cout << "warning: myChannel is getting high and there is no checks on this!" << endl;
assert(false);
}
}
pc = 0;
2007-10-20 01:35:48 +02:00
}
MessagingPort::~MessagingPort() {
2007-11-18 03:10:00 +01:00
delete pc; pc = 0;
2007-10-20 01:35:48 +02:00
}
void MessagingPort::init(int myUdpPort) {
SockAddr me(myUdpPort);
if( !conn.init(me) ) {
2007-11-18 03:10:00 +01:00
cout << "/conn init failure in MessagingPort::init " << myUdpPort << endl;
2007-10-20 01:35:48 +02:00
exit(2);
}
2007-11-18 03:10:00 +01:00
EndPoint ep;
ep.channel = myChannel;
ep.sa = me;
cout << "/Initializing MessagingPort " << ep.toString() << endl;
pc = new ProtocolConnection(conn, ep);
2007-10-20 01:35:48 +02:00
}
bool MessagingPort::recv(Message& m) {
2007-11-18 03:10:00 +01:00
MR *mr = pc->cr.recv();
2007-10-20 01:35:48 +02:00
2007-11-18 03:10:00 +01:00
Fragment *first = mr->f[0]->internals;
m.channel = first->channel;
m.from = mr->from.sa;
MsgData *somd = first->startOfMsgData();
2007-10-20 01:35:48 +02:00
int totalLen = somd->len;
2007-11-18 03:10:00 +01:00
if( mr->n() == 1 ) {
// only one fragment, so use its buffer instead of making
// a copy
2007-10-20 01:35:48 +02:00
m.setData(somd, false);
return true;
}
2007-11-18 03:10:00 +01:00
MsgData *fullmsg = (MsgData *) malloc(totalLen);
char *p = (char *) fullmsg;
for( int i = 0; i < mr->n(); i++ ) {
Fragment *frag = mr->f[i]->internals;
memcpy(p, frag->data, frag->fragmentDataLen());
p += frag->fragmentDataLen();
2007-10-20 01:35:48 +02:00
}
2007-11-18 03:10:00 +01:00
assert( p - ((char *)fullmsg) == totalLen );
mr->freeFrags();
m.setData(fullmsg, true);
2007-10-20 01:35:48 +02:00
return true;
}
void MessagingPort::reply(Message& received, Message& response) {
2007-11-18 03:10:00 +01:00
say(received.channel, received.from, response, received.data->id);
2007-10-20 01:35:48 +02:00
}
bool MessagingPort::call(SockAddr& to, Message& toSend, Message& response) {
2007-11-18 03:10:00 +01:00
assert( myChannel >= 0 );
say(myChannel, to, toSend);
2007-11-05 21:12:45 +01:00
while( 1 ) {
bool ok = recv(response);
if( !ok )
return false;
2007-11-13 22:44:01 +01:00
//cout << "got response: " << response.data->responseTo << endl;
2007-11-05 21:12:45 +01:00
if( response.data->responseTo == toSend.data->id )
break;
cout << "warning: MessagingPort::call() wrong id, skipping. got:" << response.data->responseTo << " expect:" << toSend.data->id << endl;
response.reset();
}
2007-10-20 01:35:48 +02:00
return true;
}
2007-11-18 03:10:00 +01:00
void MessagingPort::say(int channel, SockAddr& to, Message& toSend, int responseTo) {
MSGID msgid = NextMsgId;
++NextMsgId;
toSend.data->id = msgid;
2007-10-20 01:35:48 +02:00
toSend.data->responseTo = responseTo;
2007-11-18 03:10:00 +01:00
toSend.channel = channel; assert(channel>0);
EndPoint ep;
ep.channel = channel;
ep.sa = to;
MS *ms = new MS(pc, ep, msgid);
2007-10-20 01:35:48 +02:00
2007-11-18 03:10:00 +01:00
int mss = conn.mtu() - FragHeader;
2007-10-20 01:35:48 +02:00
int left = toSend.data->len;
2007-11-18 03:10:00 +01:00
int i = 0;
2007-10-20 01:35:48 +02:00
char *p = (char *) toSend.data;
2007-11-18 03:10:00 +01:00
while( left>0 ) {
int datalen = left>=mss ? mss : left;
Fragment *frag = (Fragment *)malloc(mss+FragHeader);
frag->msgId = msgid;
frag->channel = channel;
frag->fragmentLen = datalen + FragHeader;
frag->fragmentNo = i++;
memcpy(frag->data, p, datalen);
p += datalen;
ms->fragments.push_back(new F(frag));
left -= datalen;
2007-10-20 01:35:48 +02:00
}
2007-11-18 03:10:00 +01:00
ms->send();
2007-10-20 01:35:48 +02:00
}