int main (void) { // use the default event loop unless you have special needs struct ev_loop *loop = ev_default_loop (0); printf("Type help for a list of commands\n"); CBByteArray *ip = CBNewByteArrayWithDataCopy((uint8_t [16]){0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 128, 8, 126, 25}, 16); CBNetworkAddress *peeraddr = CBNewNetworkAddress(0, ip, DEFAULT_PORT, CB_SERVICE_FULL_BLOCKS, false); peer = CBNewPeerByTakingNetworkAddress(peeraddr); // Create client socket if( (sd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("socket error"); return -1; } memset(&addr, sizeof(addr), 0); addr.sin_family = AF_INET; addr.sin_port = htons(DEFAULT_PORT); addr.sin_addr.s_addr = (((((25 << 8) | 126) << 8) | 8) << 8) | 128; // Connect to server socket if(connect(sd, (struct sockaddr *)&addr, sizeof addr) < 0) { perror("Connect error"); return -1; } printf("Connected to %s:%d\n", DEFAULT_IP, DEFAULT_PORT); // initialise an io watcher, then start it // this one will watch for stdin to become readable ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); ev_io_start (loop, &stdin_watcher); // io watcher for the socket ev_io_init (&sock_watcher, sockread_cb, sd, EV_READ); ev_io_start (loop, &sock_watcher); // initialise a timer watcher, then start it ev_timer_init (&timeout_watcher, timeout_cb, 2.0, 0.); ev_timer_start (loop, &timeout_watcher); // now wait for events to arrive ev_loop (loop, 0); // unloop was called, so exit return 0; }
bool CBAddressStorageLoadAddresses(uint64_t iself, void * addrMan){ CBDatabase * database = (CBDatabase *)iself; CBAddressManager * addrManObj = addrMan; CBPosition it; // The first element shoudl be the number of addresses so get second element to begin with. if (CBAssociativeArrayGetElement(&database->index, &it, 1)) for(;;) { uint8_t * key = it.node->elements[it.index]; CBIndexValue * val = (CBIndexValue *)(key + *key + 1); if (val->length) { // Is not deleted. // Read data uint64_t file = CBDatabaseGetFile(database, val->fileID); if (NOT file) { CBLogError("Could not open a file for loading a network address."); return false; } if (NOT CBFileSeek(file, val->pos)){ CBLogError("Could not read seek a file to a network address."); return false; } if (NOT CBFileRead(file, CB_DATA_ARRAY, 20)) { CBLogError("Could not read a network address from a file."); return false; } // Create network address object and add to the address manager. CBByteArray * ip = CBNewByteArrayWithDataCopy(key + 1, 16); CBNetworkAddress * addr = CBNewNetworkAddress(CBArrayToInt64(CB_DATA_ARRAY, 0), ip, CBArrayToInt16(key, 17), (CBVersionServices) CBArrayToInt64(CB_DATA_ARRAY, 8), true); addr->penalty = CBArrayToInt32(CB_DATA_ARRAY, 16); if (NOT CBAddressManagerTakeAddress(addrManObj, addr)) { CBLogError("Could not create and add a network address to the address manager."); return false; } CBReleaseObject(ip); } if (CBAssociativeArrayIterate(&database->index, &it)) break; } return true; }
static void send_version() { CBByteArray *ip = CBNewByteArrayWithDataCopy((uint8_t [16]){0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 127, 0, 0, 1}, 16); CBByteArray *ua = CBNewByteArrayFromString("cmsc417versiona", '\00'); CBNetworkAddress * sourceAddr = CBNewNetworkAddress(0, ip, 0, CB_SERVICE_FULL_BLOCKS, false); int32_t vers = 70001; int nonce = rand(); CBVersion * version = CBNewVersion(vers, CB_SERVICE_FULL_BLOCKS, time(NULL), &peer->base, sourceAddr, nonce, ua, 0); CBMessage *message = CBGetMessage(version); char header[24]; memcpy(header + CB_MESSAGE_HEADER_TYPE, "version\0\0\0\0\0", 12); /* Compute length, serialized, and checksum */ uint32_t len = CBVersionCalculateLength(version); message->bytes = CBNewByteArrayOfSize(len); len = CBVersionSerialise(version, false); if (message->bytes) { // Make checksum uint8_t hash[32]; uint8_t hash2[32]; CBSha256(CBByteArrayGetData(message->bytes), message->bytes->length, hash); CBSha256(hash, 32, hash2); message->checksum[0] = hash2[0]; message->checksum[1] = hash2[1]; message->checksum[2] = hash2[2]; message->checksum[3] = hash2[3]; } CBInt32ToArray(header, CB_MESSAGE_HEADER_NETWORK_ID, NETMAGIC); CBInt32ToArray(header, CB_MESSAGE_HEADER_LENGTH, message->bytes->length); // Checksum memcpy(header + CB_MESSAGE_HEADER_CHECKSUM, message->checksum, 4); // Send the header send(sd, header, 24, 0); // Send the message printf("message len: %d\n", message->bytes->length); printf("checksum: %x\n", *((uint32_t *) message->checksum)); send(sd, message->bytes->sharedData->data+message->bytes->offset, message->bytes->length, 0); print_hex(message->bytes); }
} int getLen(CBBTreeNode * self); int getLen(CBBTreeNode * self){ int len = self->numElements; if (self->children[0]) for (int x = 0; x < self->numElements + 1; x++) len += getLen(self->children[x]); return len; } void addRandAddr(CBNetworkAddressManager * addrMan, int x) { CBByteArray * ip = CBNewByteArrayWithDataCopy((unsigned char []){0x20,0x01,0x0D,0xB8,0x85,0xA3,0x00,0x42,0x10,0x00,0x8A,0x2E,0x03,0x70,0x73,x/2}, 16); CBNetworkAddress * addr = CBNewNetworkAddress(1358856884 + rand() % 15, (CBSocketAddress){ip, 45562 + (rand() % 5) + 6 * (x % 2)}, CB_SERVICE_FULL_BLOCKS, true); addr->penalty = rand() % 20; CBNetworkAddressManagerTakeAddress(addrMan, addr); CBReleaseObject(ip); } int main(){ unsigned int s = (unsigned int)time(NULL); printf("Session = %ui\n", s); puts("You may need to move your mouse around if this test stalls."); srand(s);
/* socket_fd < 0 implies we need to use non-blocking connect * socket_fd >= 0 implies socket already bound to connection */ BRConnection *BRNewConnection(char *ip, uint16_t port, CBNetworkAddress *my_address, void *connector, int socket_fd) { int rtn; struct sockaddr_in remote; BRConnection *c = calloc(1, sizeof(BRConnection)); if (c == NULL) { perror("calloc failed"); exit(1); } if (socket_fd >= 0) { c->sock = socket_fd; c->flags = fcntl(c->sock, F_GETFL); } else { c->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (c->sock < 0) { perror("socket failed"); exit(1); } /* set to non-blocking, saving flags */ c->flags = fcntl(c->sock, F_GETFL); if (fcntl(c->sock, F_SETFL, c->flags | O_NONBLOCK) == -1) { perror("fcntl failed"); exit(1); } memset(&remote, 0, sizeof(remote)); remote.sin_family = AF_INET; rtn = inet_pton(AF_INET, ip, &remote.sin_addr.s_addr); if (rtn == 0) fprintf(stderr, "Address %s not valid\n", ip); else if (rtn < 0) { perror("inet_pton failed"); exit(1); } remote.sin_port = htons(port); if (connect(c->sock, (struct sockaddr *) &remote, sizeof(remote)) < 0) { if (errno == EINPROGRESS) { #ifdef BRDEBUG printf("Connection to %s:%d on socket %d in progress\n", ip, port, c->sock); #endif } else { perror("connect failed"); exit(1); } } } if (ip != NULL) { uint64_t last_seen = time(NULL); /* use IPv4 mapped IPv6 addresses as in https://en.bitcoin.it/wiki/Protocol_Specification#Network_address */ struct in_addr addr; inet_aton(ip, &addr); uint8_t *octets = (uint8_t *) &addr.s_addr; uint8_t ipmap[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, octets[0], octets[1], octets[2], octets[3]}; CBByteArray *ip_arr = CBNewByteArrayWithDataCopy(ipmap, 16); CBVersionServices services = CB_SERVICE_FULL_BLOCKS; bool is_public = true; printf("port: %d\n", port); c->address = CBNewNetworkAddress(last_seen, ip_arr, port, services, is_public); c->my_address = my_address; /* decrement reference counter */ CBReleaseObject(ip_arr); /* copy ip and port */ c->port = port; c->ip = calloc(1, strlen(ip) + 1); if (c->ip == NULL) { perror("calloc failed"); exit(1); } strcpy(c->ip, ip); } c->ver_acked = c->ver_received = 0; c->addr_sent = c->getblocks_sent = 0; c->connector = connector; /* In reality is a (BRConnector *) */ return c; }