|
30 | 30 | * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
31 | 31 | * Portions Copyright (c) 1994, Regents of the University of California
|
32 | 32 | *
|
33 |
| - *$PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.176 2005/02/22 04:35:57 momjian Exp $ |
| 33 | + *$PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.177 2005/07/30 15:17:20 momjian Exp $ |
34 | 34 | *
|
35 | 35 | *-------------------------------------------------------------------------
|
36 | 36 | */
|
|
87 | 87 | #include"libpq/libpq.h"
|
88 | 88 | #include"miscadmin.h"
|
89 | 89 | #include"storage/ipc.h"
|
90 |
| - |
| 90 | +#include"utils/guc.h" |
91 | 91 |
|
92 | 92 | /*
|
93 | 93 | * Configuration options
|
@@ -594,6 +594,19 @@ StreamConnection(int server_fd, Port *port)
|
594 | 594 | elog(LOG,"setsockopt(SO_KEEPALIVE) failed: %m");
|
595 | 595 | returnSTATUS_ERROR;
|
596 | 596 | }
|
| 597 | + |
| 598 | +/* Set default keepalive parameters. This should also catch |
| 599 | + * misconfigurations (non-zero values when socket options aren't |
| 600 | + * supported) |
| 601 | + */ |
| 602 | +if (pq_setkeepalivesidle(tcp_keepalives_idle,port)!=STATUS_OK) |
| 603 | +returnSTATUS_ERROR; |
| 604 | + |
| 605 | +if (pq_setkeepalivesinterval(tcp_keepalives_interval,port)!=STATUS_OK) |
| 606 | +returnSTATUS_ERROR; |
| 607 | + |
| 608 | +if (pq_setkeepalivescount(tcp_keepalives_count,port)!=STATUS_OK) |
| 609 | +returnSTATUS_ERROR; |
597 | 610 | }
|
598 | 611 |
|
599 | 612 | returnSTATUS_OK;
|
@@ -1158,3 +1171,199 @@ pq_endcopyout(bool errorAbort)
|
1158 | 1171 | /* in non-error case, copy.c will have emitted the terminator line */
|
1159 | 1172 | DoingCopyOut= false;
|
1160 | 1173 | }
|
| 1174 | + |
| 1175 | +int |
| 1176 | +pq_getkeepalivesidle(Port*port) |
| 1177 | +{ |
| 1178 | +#ifdefTCP_KEEPIDLE |
| 1179 | +if (IS_AF_UNIX(port->laddr.addr.ss_family)) |
| 1180 | +return0; |
| 1181 | + |
| 1182 | +if (port->keepalives_idle!=0) |
| 1183 | +returnport->keepalives_idle; |
| 1184 | + |
| 1185 | +if (port->default_keepalives_idle==0) |
| 1186 | +{ |
| 1187 | +socklen_tsize=sizeof(port->default_keepalives_idle); |
| 1188 | +if (getsockopt(port->sock,SOL_TCP,TCP_KEEPIDLE, |
| 1189 | + (char*)&port->default_keepalives_idle, |
| 1190 | +&size)<0) |
| 1191 | +{ |
| 1192 | +elog(LOG,"getsockopt(TCP_KEEPIDLE) failed: %m"); |
| 1193 | +return-1; |
| 1194 | +} |
| 1195 | +} |
| 1196 | + |
| 1197 | +returnport->default_keepalives_idle; |
| 1198 | +#else |
| 1199 | +return0; |
| 1200 | +#endif |
| 1201 | +} |
| 1202 | + |
| 1203 | +int |
| 1204 | +pq_setkeepalivesidle(intidle,Port*port) |
| 1205 | +{ |
| 1206 | +if (IS_AF_UNIX(port->laddr.addr.ss_family)) |
| 1207 | +returnSTATUS_OK; |
| 1208 | + |
| 1209 | +#ifdefTCP_KEEPIDLE |
| 1210 | +if (idle==port->keepalives_idle) |
| 1211 | +returnSTATUS_OK; |
| 1212 | + |
| 1213 | +if (port->default_keepalives_idle==0) |
| 1214 | +{ |
| 1215 | +if (pq_getkeepalivesidle(port)<0) |
| 1216 | +returnSTATUS_ERROR; |
| 1217 | +} |
| 1218 | + |
| 1219 | +if (idle==0) |
| 1220 | +idle=port->default_keepalives_idle; |
| 1221 | + |
| 1222 | +if (setsockopt(port->sock,SOL_TCP,TCP_KEEPIDLE, |
| 1223 | + (char*)&idle,sizeof(idle))<0) |
| 1224 | +{ |
| 1225 | +elog(LOG,"setsockopt(TCP_KEEPIDLE) failed: %m"); |
| 1226 | +returnSTATUS_ERROR; |
| 1227 | +} |
| 1228 | + |
| 1229 | +port->keepalives_idle=idle; |
| 1230 | +#else |
| 1231 | +if (idle!=0) |
| 1232 | +{ |
| 1233 | +elog(LOG,"setsockopt(TCP_KEEPIDLE) not supported"); |
| 1234 | +returnSTATUS_ERROR; |
| 1235 | +} |
| 1236 | +#endif |
| 1237 | + |
| 1238 | +returnSTATUS_OK; |
| 1239 | +} |
| 1240 | + |
| 1241 | +int |
| 1242 | +pq_getkeepalivesinterval(Port*port) |
| 1243 | +{ |
| 1244 | +#ifdefTCP_KEEPINTVL |
| 1245 | +if (IS_AF_UNIX(port->laddr.addr.ss_family)) |
| 1246 | +return0; |
| 1247 | + |
| 1248 | +if (port->keepalives_interval!=0) |
| 1249 | +returnport->keepalives_interval; |
| 1250 | + |
| 1251 | +if (port->default_keepalives_interval==0) |
| 1252 | +{ |
| 1253 | +socklen_tsize=sizeof(port->default_keepalives_interval); |
| 1254 | +if (getsockopt(port->sock,SOL_TCP,TCP_KEEPINTVL, |
| 1255 | + (char*)&port->default_keepalives_interval, |
| 1256 | +&size)<0) |
| 1257 | +{ |
| 1258 | +elog(LOG,"getsockopt(TCP_KEEPINTVL) failed: %m"); |
| 1259 | +return-1; |
| 1260 | +} |
| 1261 | +} |
| 1262 | + |
| 1263 | +returnport->default_keepalives_interval; |
| 1264 | +#else |
| 1265 | +return0; |
| 1266 | +#endif |
| 1267 | +} |
| 1268 | + |
| 1269 | +int |
| 1270 | +pq_setkeepalivesinterval(intinterval,Port*port) |
| 1271 | +{ |
| 1272 | +if (IS_AF_UNIX(port->laddr.addr.ss_family)) |
| 1273 | +returnSTATUS_OK; |
| 1274 | + |
| 1275 | +#ifdefTCP_KEEPINTVL |
| 1276 | +if (interval==port->keepalives_interval) |
| 1277 | +returnSTATUS_OK; |
| 1278 | + |
| 1279 | +if (port->default_keepalives_interval==0) { |
| 1280 | +if (pq_getkeepalivesinterval(port)<0) |
| 1281 | +returnSTATUS_ERROR; |
| 1282 | +} |
| 1283 | + |
| 1284 | +if (interval==0) |
| 1285 | +interval=port->default_keepalives_interval; |
| 1286 | + |
| 1287 | +if (setsockopt(port->sock,SOL_TCP,TCP_KEEPINTVL, |
| 1288 | + (char*)&interval,sizeof(interval))<0) |
| 1289 | +{ |
| 1290 | +elog(LOG,"setsockopt(TCP_KEEPINTVL) failed: %m"); |
| 1291 | +returnSTATUS_ERROR; |
| 1292 | +} |
| 1293 | + |
| 1294 | +port->keepalives_interval=interval; |
| 1295 | +#else |
| 1296 | +if (interval!=0) |
| 1297 | +{ |
| 1298 | +elog(LOG,"setsockopt(TCP_KEEPINTVL) not supported"); |
| 1299 | +returnSTATUS_ERROR; |
| 1300 | +} |
| 1301 | +#endif |
| 1302 | + |
| 1303 | +returnSTATUS_OK; |
| 1304 | +} |
| 1305 | + |
| 1306 | +int |
| 1307 | +pq_getkeepalivescount(Port*port) |
| 1308 | +{ |
| 1309 | +#ifdefTCP_KEEPCNT |
| 1310 | +if (IS_AF_UNIX(port->laddr.addr.ss_family)) |
| 1311 | +return0; |
| 1312 | + |
| 1313 | +if (port->keepalives_count!=0) |
| 1314 | +returnport->keepalives_count; |
| 1315 | + |
| 1316 | +if (port->default_keepalives_count==0) |
| 1317 | +{ |
| 1318 | +socklen_tsize=sizeof(port->default_keepalives_count); |
| 1319 | +if (getsockopt(port->sock,SOL_TCP,TCP_KEEPCNT, |
| 1320 | + (char*)&port->default_keepalives_count, |
| 1321 | +&size)<0) |
| 1322 | +{ |
| 1323 | +elog(LOG,"getsockopt(TCP_KEEPCNT) failed: %m"); |
| 1324 | +return-1; |
| 1325 | +} |
| 1326 | +} |
| 1327 | + |
| 1328 | +returnport->default_keepalives_count; |
| 1329 | +#else |
| 1330 | +return0; |
| 1331 | +#endif |
| 1332 | +} |
| 1333 | + |
| 1334 | +int |
| 1335 | +pq_setkeepalivescount(intcount,Port*port) |
| 1336 | +{ |
| 1337 | +if (IS_AF_UNIX(port->laddr.addr.ss_family)) |
| 1338 | +returnSTATUS_OK; |
| 1339 | + |
| 1340 | +#ifdefTCP_KEEPCNT |
| 1341 | +if (count==port->keepalives_count) |
| 1342 | +returnSTATUS_OK; |
| 1343 | + |
| 1344 | +if (port->default_keepalives_count==0) { |
| 1345 | +if (pq_getkeepalivescount(port)<0) |
| 1346 | +returnSTATUS_ERROR; |
| 1347 | +} |
| 1348 | + |
| 1349 | +if (count==0) |
| 1350 | +count=port->default_keepalives_count; |
| 1351 | + |
| 1352 | +if (setsockopt(port->sock,SOL_TCP,TCP_KEEPCNT, |
| 1353 | + (char*)&count,sizeof(count))<0) |
| 1354 | +{ |
| 1355 | +elog(LOG,"setsockopt(TCP_KEEPCNT) failed: %m"); |
| 1356 | +returnSTATUS_ERROR; |
| 1357 | +} |
| 1358 | + |
| 1359 | +port->keepalives_count=count; |
| 1360 | +#else |
| 1361 | +if (count!=0) |
| 1362 | +{ |
| 1363 | +elog(LOG,"setsockopt(TCP_KEEPCNT) not supported"); |
| 1364 | +returnSTATUS_ERROR; |
| 1365 | +} |
| 1366 | +#endif |
| 1367 | + |
| 1368 | +returnSTATUS_OK; |
| 1369 | +} |