+gras_error_t
+gras_trp_tcp_socket_accept(gras_socket_t *sock,
+ gras_socket_t **dst) {
+ gras_socket_t *res;
+
+ struct sockaddr_in peer_in;
+ socklen_t peer_in_len = sizeof(peer_in);
+
+ int sd;
+ int tmp_errno;
+
+ res=malloc(sizeof(gras_socket_t));
+ if (!res)
+ RAISE_MALLOC;
+
+ sd = accept(sock->sd, (struct sockaddr *)&peer_in, &peer_in_len);
+ tmp_errno = errno;
+
+ if(sd == -1) {
+ gras_socket_close(sock);
+ RAISE1(system_error,
+ "Accept failed (%s). Droping server socket.", strerror(tmp_errno));
+ } else {
+ int i = 1;
+ socklen_t s = sizeof(int);
+
+ if (setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, s)
+ || setsockopt(sd, TcpProtoNumber(), TCP_NODELAY, (char *)&i, s)) {
+ WARNING0("setsockopt failed, cannot condition the accepted socket");
+ }
+
+ i = ((gras_trp_tcp_sock_specific_t*)sock->specific)->buffsize;
+ if (setsockopt(sd, SOL_SOCKET, SO_RCVBUF, (char *)&i, s)
+ || setsockopt(sd, SOL_SOCKET, SO_SNDBUF, (char *)&i, s)) {
+ WARNING0("setsockopt failed, cannot set buffsize");
+ }
+
+ res->plugin = sock->plugin;
+ res->incoming = 1;
+ res->sd = sd;
+ res->port= -1;
+ res->peer_port= peer_in.sin_port;
+
+ if (((struct sockaddr *)&peer_in)->sa_family != AF_INET) {
+ res->peer_name = strdup("unknown");
+ } else {
+ struct in_addr addrAsInAddr;
+ char *tmp;
+
+ addrAsInAddr.s_addr = peer_in.sin_addr.s_addr;
+
+ tmp = inet_ntoa(addrAsInAddr);
+ if (tmp != NULL) {
+ res->peer_name = strdup(inet_ntoa(addrAsInAddr));
+ } else {
+ res->peer_name = strdup("unknown");
+ }
+ }
+
+ VERB3("accepted socket %d to %s:%d\n", sd, res->peer_name,res->peer_port);
+
+ *dst = res;
+
+ return no_error;
+ }