int gitno_recv(gitno_buffer *buf) { int ret; #ifdef GIT_SSL if (buf->ssl != NULL) { if ((ret = ssl_recv(buf->ssl, buf->data + buf->offset, buf->len - buf->offset)) < 0) return -1; } else { ret = p_recv(buf->fd, buf->data + buf->offset, buf->len - buf->offset, 0); if (ret < 0) { net_set_error("Error receiving socket data"); return -1; } } #else ret = p_recv(buf->fd, buf->data + buf->offset, buf->len - buf->offset, 0); if (ret < 0) { net_set_error("Error receiving socket data"); return -1; } #endif buf->offset += ret; return ret; }
static int gitno__recv(gitno_buffer *buf) { int ret; ret = p_recv(buf->socket->socket, buf->data + buf->offset, buf->len - buf->offset, 0); if (ret < 0) { net_set_error("Error receiving socket data"); return -1; } buf->offset += ret; return ret; }
static int gitno__recv_ssl(gitno_buffer *buf) { int ret; do { ret = SSL_read(buf->socket->ssl.ssl, buf->data + buf->offset, buf->len - buf->offset); } while (SSL_get_error(buf->socket->ssl.ssl, ret) == SSL_ERROR_WANT_READ); if (ret < 0) { net_set_error("Error receiving socket data"); return -1; } buf->offset += ret; return ret; }
int gitno_connect(git_transport *t, const char *host, const char *port) { struct addrinfo *info = NULL, *p; struct addrinfo hints; int ret; GIT_SOCKET s = INVALID_SOCKET; memset(&hints, 0x0, sizeof(struct addrinfo)); hints.ai_socktype = SOCK_STREAM; hints.ai_family = AF_UNSPEC; if ((ret = p_getaddrinfo(host, port, &hints, &info)) < 0) { giterr_set(GITERR_NET, "Failed to resolve address for %s: %s", host, p_gai_strerror(ret)); return -1; } for (p = info; p != NULL; p = p->ai_next) { s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (s == INVALID_SOCKET) { net_set_error("error creating socket"); break; } if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0) break; /* If we can't connect, try the next one */ gitno_close(s); s = INVALID_SOCKET; } /* Oops, we couldn't connect to any address */ if (s == INVALID_SOCKET && p == NULL) { giterr_set(GITERR_OS, "Failed to connect to %s", host); return -1; } t->socket = s; p_freeaddrinfo(info); if (t->use_ssl && ssl_setup(t, host) < 0) return -1; return 0; }
int gitno_send(gitno_socket *socket, const char *msg, size_t len, int flags) { int ret; size_t off = 0; #ifdef GIT_SSL if (socket->ssl.ctx) return gitno_send_ssl(&socket->ssl, msg, len, flags); #endif while (off < len) { errno = 0; ret = p_send(socket->socket, msg + off, len - off, flags); if (ret < 0) { net_set_error("Error sending data"); return -1; } off += ret; } return (int)off; }
int gitno_connect(gitno_socket *s_out, const char *host, const char *port, int flags) { struct addrinfo *info = NULL, *p; struct addrinfo hints; GIT_SOCKET s = INVALID_SOCKET; int ret; #ifdef GIT_WIN32 /* on win32, the WSA context needs to be initialized * before any socket calls can be performed */ WSADATA wsd; if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { giterr_set(GITERR_OS, "Winsock init failed"); return -1; } if (LOBYTE(wsd.wVersion) != 2 || HIBYTE(wsd.wVersion) != 2) { WSACleanup(); giterr_set(GITERR_OS, "Winsock init failed"); return -1; } #endif /* Zero the socket structure provided */ memset(s_out, 0x0, sizeof(gitno_socket)); memset(&hints, 0x0, sizeof(struct addrinfo)); hints.ai_socktype = SOCK_STREAM; hints.ai_family = AF_UNSPEC; if ((ret = p_getaddrinfo(host, port, &hints, &info)) < 0) { giterr_set(GITERR_NET, "Failed to resolve address for %s: %s", host, p_gai_strerror(ret)); return -1; } for (p = info; p != NULL; p = p->ai_next) { s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (s == INVALID_SOCKET) { net_set_error("error creating socket"); break; } if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0) break; /* If we can't connect, try the next one */ gitno__close(s); s = INVALID_SOCKET; } /* Oops, we couldn't connect to any address */ if (s == INVALID_SOCKET && p == NULL) { giterr_set(GITERR_OS, "Failed to connect to %s", host); p_freeaddrinfo(info); return -1; } s_out->socket = s; p_freeaddrinfo(info); #ifdef GIT_SSL if ((flags & GITNO_CONNECT_SSL) && ssl_setup(s_out, host, flags) < 0) return -1; #else /* SSL is not supported */ if (flags & GITNO_CONNECT_SSL) { giterr_set(GITERR_OS, "SSL is not supported by this copy of libgit2."); return -1; } #endif return 0; }