# # # add_file "query_client.cc" # content [7c175e09611051d71fedb7f282747361c586f367] # # add_file "query_client.hh" # content [cac3f7e03cfce0e544195e02f157f087ee3eefd3] # # patch "server.cc" # from [28e10a516fead692ae7458380b028278b2b8ff7a] # to [eb4cde556d8eae36e8a9e1edd19729a515a294fa] # # patch "server_manager.cc" # from [7d541212bc837f286f076a50f425539bb1e40f9d] # to [000bcbace0880393e118a66f7d14d5200c5f3e2f] # # patch "server_manager.hh" # from [e8ce8f0ba21d9b3584ef88bc99397f431a4a56df] # to [770b74f3f1c11a26a8ab38d6f7b97f780606beda] # # patch "sock.cc" # from [35c7fe924e267ab211b550ef0af7d835e4224687] # to [f85a25c1743784ab60f9d75a3265cc276f745725] # # patch "sock.hh" # from [9c83cf93213eae40a676161d3c29868e4d77503b] # to [e36fa1b42d04630450db64278ff939d4c72011fc] # # patch "usher.cc" # from [6f96de0f0086858777b09d4dab290835d8d6e8cc] # to [28fa8fca02016c89988ba5a670dc3756843ef658] # ============================================================ --- query_client.cc 7c175e09611051d71fedb7f282747361c586f367 +++ query_client.cc 7c175e09611051d71fedb7f282747361c586f367 @@ -0,0 +1,112 @@ +#include "buffer.hh" + +#include +using std::string; + +// packet format is: +// byte version +// byte cmd {100 if we send, 101 if we receive} +// uleb128 {size of everything after this} +// uleb128 {size of string} +// string +// { +// uleb128 {size of string} +// string +// } // only present if we're receiving + +// uleb128 is +// byte 0x80 | +// byte 0x80 | +// ... +// byte 0xff & +// +// the high bit says that this byte is not the last + +int extract_uleb128(char *p, int maxsize, int & out) +{ + out = 0; + int b = 0; + unsigned char got; + do { + if (b == maxsize) + return -1; + got = p[b]; + out += ((int)(p[b] & 0x7f))<<(b*7); + ++b; + } while ((unsigned int)(b*7) < sizeof(int)*8-1 && (got & 0x80)); + return b; +} + +int extract_vstr(char *p, int maxsize, string & out) +{ + int size; + out.clear(); + int chars = extract_uleb128(p, maxsize, size); + if (chars == -1 || chars + size > maxsize) { + return -1; + } + out.append(p+chars, size); + return chars+size; +} + +bool extract_reply(buffer & buf, string & host, string & pat) +{ + char *p; + int n, s; + buf.getread(p, n); + if (n < 4) return false; + p += 2; // first 2 bytes are header + n -= 2; + // extract size, and make sure we have the entire packet + int pos = extract_uleb128(p, n, s); + if (pos == -1 || n < s+pos) { + return false; + } + // extract host vstr + int num = extract_vstr(p+pos, n-pos, host); + if (num == -1) { + return false; + } + pos += num; + // extract pattern vstr + num = extract_vstr(p+pos, n-pos, pat); + if (num == -1) { + cerr<<"old-style reply.\n"; + pat = host; + host.clear(); + return true; + } + pos += num; + buf.fixread(pos+2); + return true; +} + +void make_packet(std::string const & msg, char * & pkt, int & size) +{ + size = msg.size(); + char const * txt = msg.c_str(); + char header[6]; + header[0] = 0; + header[1] = 100; + int headersize; + if (size >= 128) { + header[2] = 0x80 | (0x7f & (char)(size+2)); + header[3] = (char)((size+2)>>7); + header[4] = 0x80 | (0x7f & (char)(size)); + header[5] = (char)(size>>7); + headersize = 6; + } else if (size >= 127) { + header[2] = 0x80 | (0x7f & (char)(size+1)); + header[3] = (char)((size+1)>>7); + header[4] = (char)(size); + headersize = 5; + } else { + header[2] = (char)(size+1); + header[3] = (char)(size); + headersize = 4; + } + pkt = new char[headersize + size]; + memcpy(pkt, header, headersize); + memcpy(pkt + headersize, txt, size); + size += headersize; +} ============================================================ --- query_client.hh cac3f7e03cfce0e544195e02f157f087ee3eefd3 +++ query_client.hh cac3f7e03cfce0e544195e02f157f087ee3eefd3 @@ -0,0 +1,13 @@ +#ifndef __QUERY_CLIENT_HH_ +#define __QUERY_CLIENT_HH_ + +struct buffer; +namespace std { + struct string; +} + +void make_packet(std::string const & msg, char * & pkt, int & size); + +bool extract_reply(buffer & buf, std::string & host, std::string & pat); + +#endif ============================================================ --- server.cc 28e10a516fead692ae7458380b028278b2b8ff7a +++ server.cc eb4cde556d8eae36e8a9e1edd19729a515a294fa @@ -98,6 +98,67 @@ return ss; } +static bool +check_address_empty(string const & addr, int port) +{ + sock s = tosserr(socket(AF_INET, SOCK_STREAM, 0), "socket()"); + int yes = 1; + tosserr(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + &yes, sizeof(yes)), "setsockopt"); + sockaddr_in a; + memset (&a, 0, sizeof (a)); + if (!inet_aton(addr.c_str(), (in_addr *) &a.sin_addr.s_addr)) + throw errstr("bad ip address format", 0); + a.sin_port = htons(port); + a.sin_family = AF_INET; + int r = bind(s, (sockaddr *) &a, sizeof(a)); + s.close(); + return r == 0; +} + +static void +find_addr(string & addr, int & port) +{ + if (currport == 0) { + currport = minport-1; + for(int i = 0; i < 4; ++i) + curraddr[i] = minaddr[i]; + } + do { + // get the next address in our list + if (++currport > maxport) { + currport = minport; + for (int i = 0; i < 4; ++i) { + if (++curraddr[i] <= maxaddr[i]) + break; + curraddr[i] = minaddr[i]; + } + } + port = currport; + addr = lexical_cast(curraddr[0]) + "." + + lexical_cast(curraddr[1]) + "." + + lexical_cast(curraddr[2]) + "." + + lexical_cast(curraddr[3]); + } while (!check_address_empty(addr, port)); +} + +static sock +make_outgoing(int port, string const & address) +{ + sock s = tosserr(socket(AF_INET, SOCK_STREAM, 0), "socket()"); + + struct sockaddr_in a; + memset(&a, 0, sizeof(a)); + a.sin_family = AF_INET; + a.sin_port = htons(port); + + if (!inet_aton(address.c_str(), (in_addr *) &a.sin_addr.s_addr)) + throw errstr("bad ip address format", 0); + + tosserr(connect(s, (sockaddr *) &a, sizeof (a)), "connect()"); + return s; +} + sock server::connect() { ============================================================ --- server_manager.cc 7d541212bc837f286f076a50f425539bb1e40f9d +++ server_manager.cc 000bcbace0880393e118a66f7d14d5200c5f3e2f @@ -185,3 +185,11 @@ return i->second.get_state(); throw errstr("No such server."); } + +void +server_manager::kill_old_servers() +{ + set >::iterator i; + for (i = server::live.begin(); i != server::live.end(); ++i) + (*i)->maybekill(); +} ============================================================ --- server_manager.hh e8ce8f0ba21d9b3584ef88bc99397f431a4a56df +++ server_manager.hh 770b74f3f1c11a26a8ab38d6f7b97f780606beda @@ -57,6 +57,7 @@ serversock connect_to_server(string const &host, string const &pattern); void disconnect_from_server(serversock const &s); serverstate get_server_state(string const &name); + void kill_old_servers(); }; #endif ============================================================ --- sock.cc 35c7fe924e267ab211b550ef0af7d835e4224687 +++ sock.cc f85a25c1743784ab60f9d75a3265cc276f745725 @@ -108,3 +108,22 @@ return true; } set sock::all_socks; + +sock +start(string addr, int port) +{ + sock s = tosserr(socket(AF_INET, SOCK_STREAM, 0), "socket()"); + int yes = 1; + tosserr(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + &yes, sizeof(yes)), "setsockopt"); + sockaddr_in a; + memset (&a, 0, sizeof (a)); + if (!inet_aton(addr.c_str(), (in_addr *) &a.sin_addr.s_addr)) + throw errstr("bad ip address format", 0); + a.sin_port = htons(port); + a.sin_family = AF_INET; + tosserr(bind(s, (sockaddr *) &a, sizeof(a)), "bind"); + cerr<<"bound to "< -// byte 0x80 | -// ... -// byte 0xff & -// -// the high bit says that this byte is not the last - -void make_packet(std::string const & msg, char * & pkt, int & size) -{ - size = msg.size(); - char const * txt = msg.c_str(); - char header[6]; - header[0] = netsync_version; - header[1] = 100; - int headersize; - if (size >= 128) { - header[2] = 0x80 | (0x7f & (char)(size+2)); - header[3] = (char)((size+2)>>7); - header[4] = 0x80 | (0x7f & (char)(size)); - header[5] = (char)(size>>7); - headersize = 6; - } else if (size >= 127) { - header[2] = 0x80 | (0x7f & (char)(size+1)); - header[3] = (char)((size+1)>>7); - header[4] = (char)(size); - headersize = 5; - } else { - header[2] = (char)(size+1); - header[3] = (char)(size); - headersize = 4; - } - pkt = new char[headersize + size]; - memcpy(pkt, header, headersize); - memcpy(pkt + headersize, txt, size); - size += headersize; -} - - -bool check_address_empty(string const & addr, int port) -{ - sock s = tosserr(socket(AF_INET, SOCK_STREAM, 0), "socket()"); - int yes = 1; - tosserr(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - &yes, sizeof(yes)), "setsockopt"); - sockaddr_in a; - memset (&a, 0, sizeof (a)); - if (!inet_aton(addr.c_str(), (in_addr *) &a.sin_addr.s_addr)) - throw errstr("bad ip address format", 0); - a.sin_port = htons(port); - a.sin_family = AF_INET; - int r = bind(s, (sockaddr *) &a, sizeof(a)); - s.close(); - return r == 0; -} - -void find_addr(string & addr, int & port) -{ - if (currport == 0) { - currport = minport-1; - for(int i = 0; i < 4; ++i) - curraddr[i] = minaddr[i]; - } - do { - // get the next address in our list - if (++currport > maxport) { - currport = minport; - for (int i = 0; i < 4; ++i) { - if (++curraddr[i] <= maxaddr[i]) - break; - curraddr[i] = minaddr[i]; - } - } - port = currport; - addr = lexical_cast(curraddr[0]) + "." + - lexical_cast(curraddr[1]) + "." + - lexical_cast(curraddr[2]) + "." + - lexical_cast(curraddr[3]); - } while (!check_address_empty(addr, port)); -} - -sock start(string addr, int port) -{ - sock s = tosserr(socket(AF_INET, SOCK_STREAM, 0), "socket()"); - int yes = 1; - tosserr(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - &yes, sizeof(yes)), "setsockopt"); - sockaddr_in a; - memset (&a, 0, sizeof (a)); - if (!inet_aton(addr.c_str(), (in_addr *) &a.sin_addr.s_addr)) - throw errstr("bad ip address format", 0); - a.sin_port = htons(port); - a.sin_family = AF_INET; - tosserr(bind(s, (sockaddr *) &a, sizeof(a)), "bind"); - cerr<<"bound to "< >::iterator i; - for (i = server::live_servers.begin(); i != server::live_servers.end(); ++i) { - (*i)->maybekill(); - } -} -int extract_uleb128(char *p, int maxsize, int & out) -{ - out = 0; - int b = 0; - unsigned char got; - do { - if (b == maxsize) - return -1; - got = p[b]; - out += ((int)(p[b] & 0x7f))<<(b*7); - ++b; - } while ((unsigned int)(b*7) < sizeof(int)*8-1 && (got & 0x80)); - return b; -} - -int extract_vstr(char *p, int maxsize, string & out) -{ - int size; - out.clear(); - int chars = extract_uleb128(p, maxsize, size); - if (chars == -1 || chars + size > maxsize) { - return -1; - } - out.append(p+chars, size); - return chars+size; -} - -bool extract_reply(buffer & buf, string & host, string & pat) -{ - char *p; - int n, s; - buf.getread(p, n); - if (n < 4) return false; - p += 2; // first 2 bytes are header - n -= 2; - // extract size, and make sure we have the entire packet - int pos = extract_uleb128(p, n, s); - if (pos == -1 || n < s+pos) { - return false; - } - // extract host vstr - int num = extract_vstr(p+pos, n-pos, host); - if (num == -1) { - return false; - } - pos += num; - // extract pattern vstr - num = extract_vstr(p+pos, n-pos, pat); - if (num == -1) { - cerr<<"old-style reply.\n"; - pat = host; - host.clear(); - return true; - } - pos += num; - buf.fixread(pos+2); - return true; -} - bool reload_pending; map admins; string conffile;